#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include "sipsiparser.h"
#include "builderplugin.h"
#include "buildersectioncontrol.h"
#include "dvbplugin_neimenggu.h"
#include "pluginfreqtable.h"

#define PLUGIN_MONITOR_PERIOD	10000 //10s

typedef enum
{
	BUILDER_PLUGIN_IDLE,
	BUILDER_PLUGIN_WAITE_TUNER_LOCK,
	BUILDER_PLUGIN_RECV_SIPSI,
}BUILDER_PLUGIN_STATUS_T;

typedef enum
{
	BUILDER_NETWORT_SEARCH_RECV_NIT,
	BUILDER_NETWORT_SEARCH_FREQ_LOOP,
}BUILDER_NETWORT_SEARCH_STATUS;

typedef enum
{
	BUILDER_AUTO_SEARCH_SCAN_NIT,
	//BUILDER_AUTO_SEARCH_SCAN_BAT,
	BUILDER_AUTO_SEARCH_NIT_FREQ_LOOP,
	BUILDER_AUTO_SEARCH_FULL_FREQ_LOOP,
}BUILDER_AUTO_SEARCH_STATUS;

typedef enum
{
	BUILDER_MONITOR_SEARCH_RECV_NIT,
	BUILDER_MONITOR_SEARCH_RECV_BAT,
	BUILDER_MONITOR_SEARCH_RECV_PSI,
}BUILDER_MONITOR_SEARCH_STATUS;

typedef struct
{
	BUILDER_NETWORT_SEARCH_STATUS		m_eStatus;
	unsigned char 						m_au8SecRecvBitmap[256];//most 256 sections
	builder_section_t*						m_pstSections;
	unsigned int							m_u32RecvDataTimes;
	builder_tuner_t*						m_pstTunerList;
	unsigned int							m_u32Index;
	unsigned int							m_u32Total;
}builder_network_search_control_t;

typedef struct
{
	BUILDER_AUTO_SEARCH_STATUS		m_eStatus;
	unsigned char 					m_au8SecRecvBitmap[256];//most 256 sections
	builder_section_t*					m_pstSections;
	builder_section_t*					m_pstBatSections;
	builder_tuner_t*					m_pstTunerList;
	unsigned int						m_u32RecvDataTimes;
	unsigned int 						m_u32StartIndex;
	unsigned int 						m_u32EndIndex;
	unsigned int 						m_u32Index;
	unsigned int						m_u32Total;
}builder_auto_search_control_t;

typedef struct
{
	builder_tuner_t*					m_pstTunerList;
	unsigned int 						m_u32StartIndex;
	unsigned int 						m_u32EndIndex;
	unsigned int 						m_u32Index;
}builder_full_search_control_t;

typedef struct
{
	BUILDER_MONITOR_SEARCH_STATUS	m_eStatus;
	unsigned char					m_au8SecRecvBitmap[256];//most 256 sections
	builder_section_t*				m_pstNitSections;
	builder_section_t*				m_pstBatSections;
	builder_tuner_t*				m_pstTunerList;
	unsigned int					m_u32RecvDataTimes;
	unsigned int					m_u32RecvBatDataTimes;
}builder_monitor_search_control_t;

typedef union
{
	builder_network_search_control_t	m_stQuickCtrl;
	builder_auto_search_control_t	m_stAutoCtrl;
	builder_full_search_control_t		m_stFullCtrl;
	builder_monitor_search_control_t	m_stMonitorCtrl;
}builder_plugin_search_control_u;

typedef struct
{
	BUILDER_PLUGIN_STATUS_T		m_eStatus;
	BUILDER_SEARCH_TYPE_T			m_eSearchType;
	unsigned int						m_u32FilterId;
	builder_tuner_t					m_stCurTuner;
	unsigned int						m_u32Process;
	builder_section_control_t			m_stSecCtrl;
	unsigned int						m_u32DataOK;
	builder_tuner_t					m_stDataOkTunerInfo;
	unsigned int						m_u32TimeOut;
	builder_plugin_search_control_u		m_uInnerCtrl;
}builder_plugin_control_t;



dvb_funcs_t stDvbFuncsList = {0};

builder_plugin_control_t stBuilderCtrl;
builder_monitor_data_t	 g_stMonitorData;
static unsigned char s_u8monitorStopFlag = 0;

//dvb export functions
int PluginDvbSetFilter(unsigned int* phFilter, unsigned short u16Pid, unsigned char* pu8Data, unsigned char* pu8Mask, unsigned int u32Depth)
{
	int s32Ret = -1;
	if(stDvbFuncsList.m_pfDvbSetFilter)
	{
		s32Ret = stDvbFuncsList.m_pfDvbSetFilter(phFilter, u16Pid, pu8Data, pu8Mask, u32Depth);
	}
	return s32Ret;
}

int PluginDvbReleaseFilter(unsigned int hFilter)
{
	int s32Ret = -1;
	if(stDvbFuncsList.m_pfDvbReleaserFilter)
	{
		s32Ret = stDvbFuncsList.m_pfDvbReleaserFilter(hFilter);
	}
	return s32Ret;
}

int PluginDvbTunerLock(builder_tuner_t* pstFreq)
{
	int s32Ret = -1;
	PluginDvbLogcat("PluginDvbTunerLock() stDvbFuncsList.m_pfDvbTunerLock= %d\r\n", stDvbFuncsList.m_pfDvbTunerLock);
	
	if(stDvbFuncsList.m_pfDvbTunerLock)
	{
		s32Ret = stDvbFuncsList.m_pfDvbTunerLock(pstFreq);
	}
	return s32Ret;
}

int PluginDvbWriteNvm(unsigned char* pu8Data, unsigned int u32Len, unsigned int u32Offset)
{
	int s32Ret = -1;
	if(stDvbFuncsList.m_pfDvbWriteNvm)
	{
		s32Ret = stDvbFuncsList.m_pfDvbWriteNvm(pu8Data, u32Len, u32Offset);
	}
	return s32Ret;
}

int PluginDvbReadNvm(unsigned char* pu8Data, unsigned int u32Len, unsigned int u32Offset)
{
	int s32Ret = -1;
	if(stDvbFuncsList.m_pfDvbReadNvm)
	{
		s32Ret = stDvbFuncsList.m_pfDvbReadNvm(pu8Data, u32Len, u32Offset);
	}
	return s32Ret;	
}

void PluginDvbLogcat(char *ps8Format, ...)
{
	int s32Ret = -1;
	
	if(stDvbFuncsList.m_pfDvbLogcat)
	{
		char		as8Buffer[4096];
		va_list	stVa;
		int s32Len;

		va_start(stVa, ps8Format);
		s32Len = vsnprintf(as8Buffer, sizeof(as8Buffer) - 1, ps8Format, stVa);
		va_end(stVa);
		if (-1 == s32Len)
		{
			s32Len = sizeof(as8Buffer) -1;
		}
		as8Buffer[s32Len] = '\0';
		stDvbFuncsList.m_pfDvbLogcat(as8Buffer);
	}
	
	return;	
}

void* PluginDvbMemAlloc(unsigned int pu32Size)
{
	if(stDvbFuncsList.m_pfDvbMemAlloc)
	{
		return stDvbFuncsList.m_pfDvbMemAlloc(pu32Size);
	}
	return NULL;
}
void PluginDvbMemFree(void *pPointer)
{
	if(stDvbFuncsList.m_pfDvbMemFree)
	{
		stDvbFuncsList.m_pfDvbMemFree(pPointer);
	}	
}

void PluginDvbConvertString(unsigned char *pString, unsigned short len, unsigned char *lanCode)
{
	if(stDvbFuncsList.m_pfDvbConvertString)
	{
		stDvbFuncsList.m_pfDvbConvertString(pString, len, lanCode);
	}	
}

static int PluginCheckTunerInfo(builder_tuner_t* pstFreq)
{
	int s32Ret = -1;

	PluginDvbLogcat("PluginCheckTunerInfo() - entry, pstFreq = %p\r\n", pstFreq);	
	if(pstFreq)
	{
		PluginDvbLogcat("PluginCheckTunerInfo() - entry, FreqInfo = [%d, %d, %d, %d, %d]\r\n", pstFreq->m_u32Freq, pstFreq->m_u32Mod, pstFreq->m_u32Bandwidth, pstFreq->m_u32Sym, pstFreq->m_u32Tunertype);
		if(pstFreq->m_u32Freq < 42000 || pstFreq->m_u32Freq > 862000 || pstFreq->m_u32Bandwidth != 8 
			|| (pstFreq->m_u32Mod != 16 && pstFreq->m_u32Mod != 32 && pstFreq->m_u32Mod != 64 && pstFreq->m_u32Mod != 128 && pstFreq->m_u32Mod != 256))
		{
			PluginDvbLogcat("PluginCheckTunerInfo() - check error, pstFreq->m_u32Freq = %d\r\n", pstFreq->m_u32Freq );
			s32Ret = -1;
		}
		else
		{
			s32Ret = 0;
		}
	}
	PluginDvbLogcat("PluginCheckTunerInfo() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

static int PluginCheckTunerList(builder_tuner_t* pstFreqList, unsigned int* pu32Cnt)
{
	unsigned int u32Jump;
	unsigned int i;
	int s32Ret = -1;

	PluginDvbLogcat("PluginCheckTunerList() - entry, pstFreqList = %p, pu32Cnt = %p\r\n", pstFreqList, pu32Cnt);	
	if(pstFreqList && pu32Cnt)
	{
		s32Ret = 0;
		u32Jump = 0;
		for(i=0; i<*pu32Cnt; i++)
		{
			s32Ret = PluginCheckTunerInfo(&pstFreqList[i]);
			if(s32Ret == 0)
			{
				if(u32Jump > 0)
					memcpy(&pstFreqList[i-u32Jump], &pstFreqList[i], sizeof(builder_tuner_t));
			}
			else
			{
				u32Jump++;
			}
		}
		*pu32Cnt = *pu32Cnt - u32Jump;
	}
	PluginDvbLogcat("PluginCheckTunerList() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

static int PluginRecvNit()
{
	int s32Ret = -1;
	unsigned char au8Data[16];
	unsigned char au8Mask[16];

	PluginDvbLogcat("PluginRecvNit() - entry\r\n");
	memset(au8Data, 0, sizeof(au8Data));
	memset(au8Mask, 0, sizeof(au8Mask));
	au8Data[0] = SIPSI_TID_NIT_ACTUAL;
	au8Mask[0] = 0xFF;
	s32Ret = PluginDvbSetFilter(&stBuilderCtrl.m_u32FilterId, SIPSI_PID_NIT, au8Data, au8Mask, 1);
	if(s32Ret == 0)
	{
		PluginDvbLogcat("PluginRecvNit() - set filter OK\r\n");
	}
	else
	{
		PluginDvbLogcat("PluginRecvNit() - set filter error\r\n");
	}

	PluginDvbLogcat("PluginRecvNit() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

static int PluginRecvNitStop()
{
	int s32Ret = -1;

	PluginDvbLogcat("PluginRecvNitStop() - entry\r\n");
	if(stBuilderCtrl.m_u32FilterId != BUILDER_INVALID_FILTER)
	{
		s32Ret = PluginDvbReleaseFilter(stBuilderCtrl.m_u32FilterId);
		stBuilderCtrl.m_u32FilterId = BUILDER_INVALID_FILTER;
	}

	PluginDvbLogcat("PluginRecvNitStop() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}


int PluginFreeTable(builder_section_t* pstSection)
{
	int s32Ret = -1;
	builder_section_t* pstNextSection = NULL;
	
	PluginDvbLogcat("PluginFreeTable() - entry, pstSection = %p\r\n", pstSection);
	if(pstSection)
	{
		while(pstSection)
		{
			pstNextSection = pstSection->m_pstNext;
			PluginDvbMemFree(pstSection);
			pstSection = pstNextSection;
		}
		s32Ret = 0;
	}
	PluginDvbLogcat("PluginFreeTable() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

static int PluginQuickFreeNit()
{
	int s32Ret = -1;

	PluginDvbLogcat("PluginQuickFreeNit() - entry, pstSection = %p\r\n");
	if(stBuilderCtrl.m_eSearchType == BUILDER_SEARCH_NETWORK_SEARCH)
	{
		if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstSections)
		{
			s32Ret = PluginFreeTable(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstSections);
		}
	}
	PluginDvbLogcat("PluginQuickFreeNit() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginCreatSectionNode(builder_section_t** ppSectionNode, unsigned char* pu8Data)
{
	int s32Ret = -1;
	unsigned short u16SectionLen;
	
	PluginDvbLogcat("PluginCreatSectionNode() - entry, ppSectionNode = %p, pu8Data = %p\r\n", ppSectionNode, pu8Data);
	if(ppSectionNode && pu8Data)
	{
		u16SectionLen = SiPsiGetSectionLength(pu8Data);
		u16SectionLen += 3;
		*ppSectionNode = PluginDvbMemAlloc(u16SectionLen+sizeof(builder_section_t));
		if(*ppSectionNode)
		{
			memcpy((*ppSectionNode)->m_au8Section, pu8Data, u16SectionLen);
			(*ppSectionNode)->m_pstNext = NULL;
			s32Ret = 0;
		}
	}
	PluginDvbLogcat("PluginCreatSectionNode() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginGetConfig(builder_plugin_cfg_t* pstConfig)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginGetUpdateConfig() - entry, peConfig = %p\r\n", pstConfig);
	if(pstConfig)
	{
		pstConfig->m_eUpdate = BUILDER_PROGRAM_UPDATE_NIT_CHANGLE_NEW_SEARCH|BUILDER_PROGRAM_UPDATE_BACKGROUND_AND_NOTIFY;
		pstConfig->m_eSearchType = BUILDER_SEARCH_WITH_MANUL|BUILDER_SEARCH_WITH_AUTO|BUILDER_SEARCH_WITH_QUICK;
		pstConfig->m_eChannelChangeType = BUILDER_PROGRAM_CHANGE_IN_TURN;
		pstConfig->m_eChannelShowType = BUILDER_PROGRAM_SHOW_INDEX;
		pstConfig->m_u32MonitorPeriod = PLUGIN_MONITOR_PERIOD;
		pstConfig->m_u8MonitorSwitch	= 0;
		s32Ret = 0;
	}
	PluginDvbLogcat("PluginGetUpdateConfig() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginManaulSearchStart(builder_manual_search_t* pstParam)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginManaulSearchStart() - entry, pstParam = %p\r\n", pstParam);
	if(pstParam)
	{
		s32Ret = PluginCheckTunerInfo(&pstParam->m_stTunerInfo);
		if(0 == s32Ret)
		{
			memcpy(&stBuilderCtrl.m_stCurTuner, &pstParam->m_stTunerInfo, sizeof(builder_tuner_t));
			s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
			stBuilderCtrl.m_u32Process = 0;
			stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
			stBuilderCtrl.m_u32TimeOut = 2;//lock time out 2s
		}
		else
		{
			PluginDvbLogcat("PluginManaulSearchStart() - check tuner info error\r\n");
			s32Ret = -1;
		}
	}
	PluginDvbLogcat("PluginManaulSearchStart() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
}

int PluginQuickSearchStart(builder_network_search_t* pstParam)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginQuickSearchStart() - entry\r\n");
	if(pstParam)
	{
		s32Ret = PluginCheckTunerInfo(&pstParam->m_stTunerInfo);
		if(0 == s32Ret)
		{
			memcpy(&stBuilderCtrl.m_stCurTuner, &pstParam->m_stTunerInfo, sizeof(builder_tuner_t));
			s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
			stBuilderCtrl.m_u32Process = 0;
			stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstSections = NULL;
			stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
			stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus = BUILDER_NETWORT_SEARCH_RECV_NIT;
			stBuilderCtrl.m_u32TimeOut = 2;
		}
		else
		{
			PluginDvbLogcat("PluginManaulSearchStart() - check tuner info error\r\n");
			s32Ret = -1;
		}
	}
	PluginDvbLogcat("PluginQuickSearchStart() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;		
}

int PluginFullSearchStart(builder_all_search_t* pstParam)
{
	int s32Ret = -1;
	unsigned int u32FreqCnt;
	unsigned int i;
	
	PluginDvbLogcat("PluginFullSearchStart() - entry\r\n");
	if(pstParam)
	{
		u32FreqCnt = 0;
		stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_pstTunerList = PluginGetFreqTable(&u32FreqCnt);
		s32Ret = PluginCheckTunerInfo(&pstParam->m_stStartTunerInfo);
		if(s32Ret == 0)
		{
			s32Ret = PluginCheckTunerInfo(&pstParam->m_stEndTunerInfo);
			if(s32Ret == 0)
			{
				stBuilderCtrl.m_eSearchType = BUILDER_SEARCH_FULL_SEARCH;
				if(pstParam->m_stStartTunerInfo.m_u32Freq < pstParam->m_stEndTunerInfo.m_u32Freq)
				{
					i = 0;
					while(stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_pstTunerList[i].m_u32Freq < pstParam->m_stStartTunerInfo.m_u32Freq)
						i++;
					if(stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_pstTunerList[i].m_u32Freq == pstParam->m_stStartTunerInfo.m_u32Freq)
						stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32StartIndex = i;
					else
						stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32StartIndex = i + 1;

					i++;
					while(stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_pstTunerList[i].m_u32Freq < pstParam->m_stEndTunerInfo.m_u32Freq)
						i++;
					stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32EndIndex = i;

					stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32Index = stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32StartIndex;
					memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32StartIndex], sizeof(builder_tuner_t));
					s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
					stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
					stBuilderCtrl.m_u32TimeOut = 2;
				}
				else
				{
					s32Ret = -1;
					PluginDvbLogcat("PluginFullSearchStart() - start freq = %d < end freq = %d\r\n", pstParam->m_stStartTunerInfo.m_u32Freq, pstParam->m_stEndTunerInfo.m_u32Freq);
				}
			}
		}
	}
	PluginDvbLogcat("PluginFullSearchStart() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;		
}

builder_tuner_t astMainFreq[] = 
{
	{235000, 6875, 64, 8, BUILDER_TUNER_DVBC}
};

int PluginAutoSearchStart()
{
	int s32Ret = -1;
	unsigned int i = 0;
	unsigned int u32FreqCnt;
	
	PluginDvbLogcat("PluginAutoSearchStart() - entry\r\n");
	u32FreqCnt = 0;
	stBuilderCtrl.m_u32Process = 0;
	memset(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_au8SecRecvBitmap, 0, sizeof(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_au8SecRecvBitmap));
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList = astMainFreq;//PluginGetFreqTable(&u32FreqCnt);
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus= BUILDER_AUTO_SEARCH_SCAN_NIT;
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections = NULL;
	
	//while(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[i].m_u32Freq < 200000)
		//i++;
		
	i = 0;
	u32FreqCnt = 1;

	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex = i;
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex = i + u32FreqCnt/2;
	if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex >= u32FreqCnt)
		stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex = u32FreqCnt - 1;
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index = stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex;

	memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex], sizeof(builder_tuner_t));
	s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
	stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;

	//memset(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_au8SecRecvBitmap, 0, sizeof(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_au8SecRecvBitmap));
	//s32Ret = PluginAutoSearchEnterFullFreqLoop();

	PluginDvbLogcat("PluginAutoSearchStart() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;		
}

int PluginBootUpdateStart()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginManaulSearchStart() - entry\r\n");
	
	PluginDvbLogcat("PluginManaulSearchStart() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;		
}

int PluginSearchStart(builder_plugin_search_param_t* pstParam)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginSearchStart() - entry, pstParam = %p\r\n", pstParam);
	if(pstParam)
	{
		if(stBuilderCtrl.m_eStatus == BUILDER_PLUGIN_IDLE)
		{
			s32Ret = 0;
			stBuilderCtrl.m_u32Process = 0;
			stBuilderCtrl.m_u32DataOK = 0;
			stBuilderCtrl.m_eSearchType = pstParam->m_eSearchType;
			switch(pstParam->m_eSearchType)
			{
				case BUILDER_SEARCH_MANUAL_SEARCH:
				{
					s32Ret = PluginManaulSearchStart(&pstParam->m_uParam.m_stManualSearchParam);
					break;
				}
				case BUILDER_SEARCH_NETWORK_SEARCH:
				{
					s32Ret = PluginQuickSearchStart(&pstParam->m_uParam.m_stNetSearchParam);
					break;
				}
				case BUILDER_SEARCH_FULL_SEARCH:
				{
					s32Ret = PluginFullSearchStart(&pstParam->m_uParam.m_stAllSearchParam);
					break;
				}
				case BUILDER_SEARCH_AUTO_SEARCH:
				{
					s32Ret = PluginAutoSearchStart();
					break;
				}
				case BUILDER_SEARCH_BOOT_UPDATE:
				{
					s32Ret = PluginBootUpdateStart();
					break;
				}
				default:
				{
					break;
				}
			}
		}
		else
		{
			PluginDvbLogcat("PluginSearchStart() - receive start msg when status is not idle\r\n");
		}
	}
	PluginDvbLogcat("PluginSearchStart() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
}

int PluginManualSearchReset()
{
	int s32Ret = -1;

	PluginDvbLogcat("PluginManualSearchReset() - entry\r\n");
	if(stBuilderCtrl.m_eSearchType == BUILDER_SEARCH_MANUAL_SEARCH)
	{
		stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
		stBuilderCtrl.m_u32DataOK = 0;
		stBuilderCtrl.m_u32Process = 0;
		s32Ret = PluginSectionDataStop(&stBuilderCtrl.m_stSecCtrl);
	}
	PluginDvbLogcat("PluginManualSearchReset() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
}

int PluginQuickFreeTunerList()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginQuickFreeTunerList() - entry\r\n");
	if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList)
	{
		PluginDvbMemFree(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList);
		stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList = NULL;
	}
	PluginDvbLogcat("PluginQuickFreeTunerList() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginQuickSearchReset()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginQuickSearchReset() - entry\r\n");
	if(stBuilderCtrl.m_eSearchType == BUILDER_SEARCH_NETWORK_SEARCH)
	{
		stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
		stBuilderCtrl.m_u32DataOK = 0;
		stBuilderCtrl.m_u32Process = 0;
		if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus == BUILDER_NETWORT_SEARCH_RECV_NIT)
		{
			s32Ret = PluginRecvNitStop();
			if(s32Ret != 0)
				PluginDvbLogcat("PluginQuickSearchReset() - PluginRecvNitStop, error\r\n");
			
			s32Ret = PluginQuickFreeNit();
			if(s32Ret != 0)
				PluginDvbLogcat("PluginQuickSearchReset() - PluginQuickFreeNit error\r\n");
		}
		else if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus == BUILDER_NETWORT_SEARCH_FREQ_LOOP)
		{
			s32Ret = PluginSectionDataStop(&stBuilderCtrl.m_stSecCtrl);
			if(s32Ret != 0)
				PluginDvbLogcat("PluginQuickSearchReset() -PluginSectionDataStop error\r\n");

			s32Ret = PluginQuickFreeTunerList();
			if(s32Ret != 0)
				PluginDvbLogcat("PluginQuickSearchReset() -PluginQuickFreeTunerList error\r\n");
		}
	}
	PluginDvbLogcat("PluginQuickSearchReset() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;		
}

int PluginAutoFreeTunerList()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginAutoFreeTunerList() - entry\r\n");
	if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList)
	{
		PluginDvbMemFree(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList);
		stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList = NULL;
		s32Ret = 0;
	}
	PluginDvbLogcat("PluginAutoFreeTunerList() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;

}

static int PluginAutoFreeNit()
{
	int s32Ret = -1;

	PluginDvbLogcat("PluginAutoFreeNit() - entry, pstSection = %p\r\n");
	if(stBuilderCtrl.m_eSearchType == BUILDER_SEARCH_AUTO_SEARCH)
	{
		if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections)
		{
			s32Ret = PluginFreeTable(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections);
			if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections)
			{
				PluginDvbLogcat("PluginAutoFreeNit() - pstSection = %p\r\n");
				stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections = NULL;
			}
		}
	}
	PluginDvbLogcat("PluginAutoFreeNit() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginAutoSearchReset()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginAutoSearchReset() - entry\r\n");
	if(stBuilderCtrl.m_eSearchType == BUILDER_SEARCH_AUTO_SEARCH)
	{
		stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
		stBuilderCtrl.m_u32DataOK = 0;
		stBuilderCtrl.m_u32Process = 0;
		if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus == BUILDER_AUTO_SEARCH_SCAN_NIT)
		{
			s32Ret = PluginRecvNitStop();
			if(s32Ret != 0)
				PluginDvbLogcat("PluginAutoSearchReset() - PluginRecvNitStop, error\r\n");
			
			s32Ret = PluginAutoFreeNit();
			if(s32Ret != 0)
				PluginDvbLogcat("PluginAutoSearchReset() - PluginAutoFreeNit error\r\n");
		}
		else if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus == BUILDER_AUTO_SEARCH_NIT_FREQ_LOOP)
		{
			s32Ret = PluginSectionDataStop(&stBuilderCtrl.m_stSecCtrl);
			if(s32Ret != 0)
				PluginDvbLogcat("PluginAutoSearchReset() -PluginSectionDataStop error\r\n");

			s32Ret = PluginAutoFreeTunerList();
			if(s32Ret != 0)
				PluginDvbLogcat("PluginAutoSearchReset() -PluginAutoFreeTunerList error\r\n");
		}
		else if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus == BUILDER_AUTO_SEARCH_FULL_FREQ_LOOP)
		{
			s32Ret = PluginSectionDataStop(&stBuilderCtrl.m_stSecCtrl);
			if(s32Ret != 0)
				PluginDvbLogcat("PluginAutoSearchReset() -PluginSectionDataStop error\r\n");
		}
	}
	PluginDvbLogcat("PluginAutoSearchReset() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
}

int PluginFullSearchReset()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginFullSearchReset() - entry\r\n");	
	if(stBuilderCtrl.m_eSearchType == BUILDER_SEARCH_FULL_SEARCH)
	{
		stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
		stBuilderCtrl.m_u32DataOK = 0;
		stBuilderCtrl.m_u32Process = 0;
		PluginSectionDataStop(&stBuilderCtrl.m_stSecCtrl);
	}
	PluginDvbLogcat("PluginFullSearchReset() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;		
}

int PluginBootSearchReset()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginBootSearchReset() - entry\r\n");
	if(stBuilderCtrl.m_eSearchType == BUILDER_SEARCH_BOOT_UPDATE)
	{
		stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
	}
	PluginDvbLogcat("PluginBootSearchReset() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;		
}

int PluginStatusReset()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginStatusReset() - entry\r\n");
	if(stBuilderCtrl.m_eStatus != BUILDER_PLUGIN_IDLE)
	{
		switch(stBuilderCtrl.m_eSearchType)
		{
			case BUILDER_SEARCH_MANUAL_SEARCH:
			{
				s32Ret = PluginManualSearchReset();
				break;
			}
			case BUILDER_SEARCH_NETWORK_SEARCH:
			{
				s32Ret = PluginQuickSearchReset();
				break;
			}
			case BUILDER_SEARCH_FULL_SEARCH:
			{
				s32Ret = PluginFullSearchReset();
				break;
			}
			case BUILDER_SEARCH_AUTO_SEARCH:
			{
				s32Ret = PluginAutoSearchReset();
				break;
			}
			case BUILDER_SEARCH_BOOT_UPDATE:
			{
				s32Ret = PluginBootSearchReset();
				break;
			}
			default:
				PluginDvbLogcat("PluginStatusReset() - error type\r\n");
				break;
		}
	}
	PluginDvbLogcat("PluginStatusReset() - return, s32Ret = %d\r\n", s32Ret);
	
	return s32Ret;		
}

int PluginSearchStop()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginSearchStop() - entry\r\n");
	s32Ret = PluginStatusReset();
	PluginDvbLogcat("PluginSearchStop() - return, s32Ret = %d\r\n", s32Ret);
	
	return s32Ret;	
}

int PluginManualSearchLockFinish(builder_tuner_t* pstTunerInfo, unsigned int u32Lock)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginManualSearchLockFinish() - entry, pstTunerInfo = %p, u32Lock = %d\r\n", pstTunerInfo, u32Lock);
	if(pstTunerInfo)
	{
		if(u32Lock == 1)
		{
			stBuilderCtrl.m_u32TimeOut = 4;
			s32Ret = PluginSectionDataReset(&stBuilderCtrl.m_stSecCtrl);
			if(s32Ret == 0)
			{
				s32Ret = PluginSectionDataStart(&stBuilderCtrl.m_stSecCtrl);
				stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_RECV_SIPSI;
				stBuilderCtrl.m_u32Process = MANUAL_SCAN_LOCK_PROCESS;
			}
			else
			{
				PluginDvbLogcat("PluginManualSearchLockFinish() - start recv sdt error\r\n");
				stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
				stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
			}
		}
		else
		{
			PluginDvbLogcat("PluginManualSearchLockFinish() - u32Lock = 0, pstTunerInfo->m_u32Freq = %d\r\n", pstTunerInfo->m_u32Freq);
			s32Ret = 0;
			stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
			stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
		}
	}
	PluginDvbLogcat("PluginManualSearchLockFinish() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginQuickSearchLockFinish(builder_tuner_t* pstTunerInfo, unsigned int u32Lock)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginQuickSearchLockFinish() - entry, pstTunerInfo = %p, u32Lock = %d\r\n", pstTunerInfo, u32Lock);
	if(pstTunerInfo)
	{
		if(u32Lock == 1)
		{
			if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus == BUILDER_NETWORT_SEARCH_RECV_NIT)
			{
				stBuilderCtrl.m_u32TimeOut = 10;
				stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32RecvDataTimes = 0;
				s32Ret = PluginRecvNit();
				if(s32Ret == 0)
				{
					stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_RECV_SIPSI;
					stBuilderCtrl.m_u32Process = QUICK_SCAN_NIT_PROCESS;// 2%
					memset(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_au8SecRecvBitmap, 0, sizeof(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_au8SecRecvBitmap));
					stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index = 0;
				}
				else
				{
					PluginDvbLogcat("PluginQuickSearchLockFinish() - recv nit failed\r\n");
				}
			}
			else if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus == BUILDER_NETWORT_SEARCH_FREQ_LOOP)
			{
				stBuilderCtrl.m_u32TimeOut = 4;
				if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index < stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total)
				{
					s32Ret = PluginSectionDataReset(&stBuilderCtrl.m_stSecCtrl);
					if(s32Ret == 0)
					{
						s32Ret = PluginSectionDataStart(&stBuilderCtrl.m_stSecCtrl);
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_RECV_SIPSI;
					}
					else
					{
						stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;// 100%
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
						PluginDvbLogcat("PluginQuickSearchLockFinish() - start sipsi recv error\r\n");
					}
				}
				else
				{
					stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
					PluginDvbLogcat("PluginQuickSearchLockFinish() - recv error lock msge while m_u32Index = %d, m_u32Total = %d\r\n", stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index, stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total);
				}
			}
			else
			{
				PluginDvbLogcat("PluginQuickSearchLockFinish() - error status stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus = %d\r\n", stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus);
			}
		}
		else
		{
			PluginDvbLogcat("PluginQuickSearchLockFinish() - u32Lock = 0, pstTunerInfo->m_u32Freq = %d\r\n", pstTunerInfo->m_u32Freq);
			if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus == BUILDER_NETWORT_SEARCH_RECV_NIT)
			{
				stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;// 100%
				stBuilderCtrl.m_u32DataOK = 0;
				stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
				PluginDvbLogcat("PluginQuickSearchLockFinish() - lock NIT Freq error\r\n");
			}
			else if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus == BUILDER_NETWORT_SEARCH_FREQ_LOOP)
			{
				stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index++;
				stBuilderCtrl.m_u32Process = (QUICK_SCAN_NIT_PROCESS+QUICK_SCAN_LOCK_PROCESS) +  QUICK_SCAN_SIPSI_PROCESS*stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index/stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total;//section control 96%, tuner lock 2%, nit recv 2%
				PluginDvbLogcat("PluginQuickSearchLockFinish() - stBuilderCtrl.m_u32Process = %d, [%d/%d]\r\n",stBuilderCtrl.m_u32Process, stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index, stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total);		
				if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total > stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index)
				{
					memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index], sizeof(builder_tuner_t));
					PluginDvbLogcat("PluginQuickSearchLockFinish() - start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
					s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
					stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
				}
				else
				{
					stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
					stBuilderCtrl.m_u32DataOK = 0;
					stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
				}				
			}
			else
			{
				PluginDvbLogcat("PluginQuickSearchLockFinish() - error status stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus = %d\r\n", stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus);
			}
		}
	}
	PluginDvbLogcat("PluginQuickSearchLockFinish() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginFullSearchLockFinish(builder_tuner_t* pstTunerInfo, unsigned int u32Lock)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginFullSearchLockFinish() - entry, pstTunerInfo = %p, u32Lock = %d\r\n", pstTunerInfo, u32Lock);
	if(pstTunerInfo)
	{
		if(u32Lock == 1)
		{
			s32Ret = PluginSectionDataReset(&stBuilderCtrl.m_stSecCtrl);
			if(s32Ret == 0)
			{
				stBuilderCtrl.m_u32TimeOut = 4;
				s32Ret = PluginSectionDataStart(&stBuilderCtrl.m_stSecCtrl);
				PluginSearchSetProcess(0, SCAN_ALL_PROCESS, 0);

				stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_RECV_SIPSI;
			}
			else
			{
				stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
				PluginDvbLogcat("PluginFullSearchLockFinish() - start recv sdt error\r\n");
			}
		}
		else
		{
			stBuilderCtrl.m_u32DataOK = 0;
			stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32Index++;
			PluginSearchSetProcess(0, SCAN_ALL_PROCESS, 0);
			
			if(stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32Index <= stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32EndIndex)
			{
				PluginSectionDataReset(&stBuilderCtrl.m_stSecCtrl);
				memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32Index], sizeof(builder_tuner_t));
				PluginDvbLogcat("PluginFullSearchLockFinish() - start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
				s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
				stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;	
			}
			else
			{
				PluginDvbLogcat("PluginFullSearchLockFinish() - all freq index end [%d~%d]\r\n", stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32StartIndex, stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32EndIndex);
				s32Ret = 0;
				stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
				stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;	
			}
		}
	}
	PluginDvbLogcat("PluginFullSearchLockFinish() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginAutoSearchLockFinish(builder_tuner_t* pstTunerInfo, unsigned int u32Lock)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginAutoSearchLockFinish() - entry, pstTunerInfo = %p, u32Lock = %d\r\n", pstTunerInfo, u32Lock);
	if(pstTunerInfo)
	{
		switch(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus)
		{
			case BUILDER_AUTO_SEARCH_SCAN_NIT:
			{
				if(u32Lock == 1)
				{
					stBuilderCtrl.m_u32TimeOut = 10;
					PluginSearchSetProcess(0, AUTO_SCAN_NIT_PROCESS, 0);

					stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32RecvDataTimes = 0;
					s32Ret = PluginRecvNit();

					if(s32Ret == 0)
					{	
						PluginDvbLogcat("PluginAutoSearchLockFinish() - recv nit OK\r\n");
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_RECV_SIPSI;
					}
					else
					{
						PluginDvbLogcat("PluginAutoSearchLockFinish() - recv nit not OK\r\n");
						PluginRecvNitStop();
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
					}
				}
				else
				{
					stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index++;
					PluginSearchSetProcess(0, AUTO_SCAN_NIT_PROCESS, 0);
					
					if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index < stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex)
					{
						memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index], sizeof(builder_tuner_t));
						s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
					}
					else
					{
						PluginRecvNitStop();
						s32Ret = PluginAutoSearchEnterFullFreqLoop();
					}
				}
				break;
			}
			case BUILDER_AUTO_SEARCH_NIT_FREQ_LOOP:
			{
				if(u32Lock == 1)
				{
					PluginSearchSetProcess(AUTO_SCAN_NIT_PROCESS, AUTO_SCAN_SIPSI_PROCESS, 0);

					stBuilderCtrl.m_u32TimeOut = 4;
					s32Ret = PluginSectionDataReset(&stBuilderCtrl.m_stSecCtrl);
					if(s32Ret == 0)
					{
						s32Ret = PluginSectionDataStart(&stBuilderCtrl.m_stSecCtrl);
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_RECV_SIPSI;
					}
					else
					{
						stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;// 100%
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
						PluginDvbLogcat("PluginAutoSearchLockFinish() - start sipsi recv error\r\n");
					}
				}
				else//next freq
				{
					s32Ret = 0;
					stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index++;
					PluginSearchSetProcess(AUTO_SCAN_NIT_PROCESS, AUTO_SCAN_SIPSI_PROCESS, 0);

					PluginDvbLogcat("PluginAutoSearchLockFinish() - stBuilderCtrl.m_u32Process = %d, [%d/%d]\r\n",stBuilderCtrl.m_u32Process, stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index, stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total);		
					if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total > stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index)
					{
						memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index], sizeof(builder_tuner_t));
						PluginDvbLogcat("PluginAutoSearchLockFinish() - start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
						s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
					}
					else
					{
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
						stBuilderCtrl.m_u32DataOK = 0;
						stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
					}				
				}
				break;
			}
			case BUILDER_AUTO_SEARCH_FULL_FREQ_LOOP:
			{
				if(u32Lock == 1)
				{
					PluginSearchSetProcess(AUTO_SCAN_NIT_PROCESS, AUTO_SCAN_SIPSI_PROCESS, 0);

					s32Ret = PluginSectionDataReset(&stBuilderCtrl.m_stSecCtrl);
					if(s32Ret == 0)
					{
						s32Ret = PluginSectionDataStart(&stBuilderCtrl.m_stSecCtrl);
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_RECV_SIPSI;
					}
					else
					{
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
						PluginDvbLogcat("PluginFullSearchLockFinish() - start recv sdt error\r\n");
					}
				}
				else
				{
					s32Ret = 0;
					stBuilderCtrl.m_u32DataOK = 0;
					stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index++;
					PluginSearchSetProcess(AUTO_SCAN_NIT_PROCESS, AUTO_SCAN_SIPSI_PROCESS, 0);

					if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index <= stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex)
					{
						memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index], sizeof(builder_tuner_t));
						PluginDvbLogcat("PluginFullSearchLockFinish() - start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
						s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;	
					}
					else
					{
						PluginDvbLogcat("PluginFullSearchLockFinish() - all freq index end [%d~%d]\r\n", stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex, stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex);
						stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;	
					}
				}
				break;
			}
			default:
			{
				break;
			}
		}
	}
	PluginDvbLogcat("PluginAutoSearchLockFinish() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginBootUpdateLockFinish(builder_tuner_t* pstTunerInfo, unsigned int u32Lock)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginBootUpdateLockFinish() - entry, pstTunerInfo = %p, u32Lock = %d\r\n", pstTunerInfo, u32Lock);
	PluginDvbLogcat("PluginBootUpdateLockFinish() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginLockFinish(builder_tuner_t* pstTunerInfo, unsigned int u32Lock)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginLockFinish() - entry\r\n");
	if(pstTunerInfo)
	{
		PluginDvbLogcat("PluginLockFinish() - stBuilderCtrl.m_eStatus = %d\r\n",stBuilderCtrl.m_eStatus);
		if(stBuilderCtrl.m_eStatus == BUILDER_PLUGIN_WAITE_TUNER_LOCK)
		{
			if(stBuilderCtrl.m_stCurTuner.m_u32Freq==pstTunerInfo->m_u32Freq) //&& stBuilderCtrl.m_stCurTuner.m_u32Sym==pstTunerInfo->m_u32Sym
				//&& stBuilderCtrl.m_stCurTuner.m_u32Mod==pstTunerInfo->m_u32Mod)
			{
				s32Ret = 0;
				switch(stBuilderCtrl.m_eSearchType)
				{
					case BUILDER_SEARCH_MANUAL_SEARCH:
					{
						s32Ret = PluginManualSearchLockFinish(pstTunerInfo, u32Lock);
						break;
					}
					case BUILDER_SEARCH_NETWORK_SEARCH:
					{
						s32Ret = PluginQuickSearchLockFinish(pstTunerInfo, u32Lock);
						break;
					}
					case BUILDER_SEARCH_FULL_SEARCH:
					{
						s32Ret = PluginFullSearchLockFinish(pstTunerInfo, u32Lock);
						break;
					}
					case BUILDER_SEARCH_AUTO_SEARCH:
					{
						s32Ret = PluginAutoSearchLockFinish(pstTunerInfo, u32Lock);
						break;
					}
					case BUILDER_SEARCH_BOOT_UPDATE:
					{
						s32Ret = PluginBootUpdateLockFinish(pstTunerInfo, u32Lock);
						break;
					}
					default:
					{
						PluginDvbLogcat("PluginLockFinish() - error search type, something wrong\r\n");
						break;
					}
				}
			}
		}
	}
	PluginDvbLogcat("PluginLockFinish() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
}

int PluginGetProcess(unsigned int* pu32DataOk, unsigned int* pu32Process)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginGetProcess() - entry, pu32DataOk = %p, pu32Process = %p\r\n", pu32DataOk, pu32Process);
	if(pu32DataOk && pu32Process)
	{
		*pu32DataOk = stBuilderCtrl.m_u32DataOK;
		*pu32Process = stBuilderCtrl.m_u32Process;
		if(*pu32Process == SCAN_ALL_PROCESS)
			stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
		s32Ret = 0;
	}
	PluginDvbLogcat("PluginGetProcess() - return, s32Ret = %d\r\n", s32Ret);
	
	return s32Ret;	
}

int PluginSearchSetProcess(unsigned int preProcess, unsigned int remainProcess, unsigned int u32SecProcess)
{
	int s32Ret = -1;
	unsigned int u32Cnt;
	unsigned int u32Index;
	unsigned int u32Process = stBuilderCtrl.m_u32Process;
	s32Ret = 0;
	switch (stBuilderCtrl.m_eSearchType)
	{
		case BUILDER_SEARCH_AUTO_SEARCH:
		{
			u32Index = stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index - stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex;
			u32Cnt = stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex - stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex + 1;
			break;
		}
		case BUILDER_SEARCH_FULL_SEARCH:
		{
			u32Index = stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32Index - stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32StartIndex;
			u32Cnt = stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32EndIndex - stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32StartIndex + 1;
			break;
		}
		default:
		{
			u32Index = 0;
			u32Cnt = 0;
			break;
		}
	}
	
	stBuilderCtrl.m_u32Process = preProcess + remainProcess*u32Index/u32Cnt;

	if (u32SecProcess) {
		stBuilderCtrl.m_u32Process += (u32SecProcess*(remainProcess/u32Cnt))/SCAN_ALL_PROCESS;
	}

	if (u32Process > stBuilderCtrl.m_u32Process) {
		stBuilderCtrl.m_u32Process = u32Process;
	}
	return s32Ret;
}

int PluginManualSearchHandleDataRecved(unsigned char* pu8Data, unsigned int hFilter)
{
	int s32Ret = -1;
	unsigned int u32Process;

	PluginDvbLogcat("PluginManualSearchHandleDataRecved() - entry, pu8Data = %p, hFilter = %x\r\n", pu8Data, hFilter);
	if(pu8Data)
	{
		stBuilderCtrl.m_u32TimeOut = 4;
		s32Ret = PluginSectionDataRecv(&stBuilderCtrl.m_stSecCtrl, hFilter, pu8Data);
		if(s32Ret == 0)
		{
			s32Ret = PluginSectionDataGetProcess(&stBuilderCtrl.m_stSecCtrl, &u32Process);
			if(s32Ret == 0)
			{
				stBuilderCtrl.m_u32Process = MANUAL_SCAN_LOCK_PROCESS + (u32Process*(MANUAL_SCAN_SIPSI_PROCESS)/SCAN_ALL_PROCESS);//section control 90%, tuner lock 10%
				if(u32Process == SCAN_ALL_PROCESS)
				{
					memcpy(&stBuilderCtrl.m_stDataOkTunerInfo, &stBuilderCtrl.m_stCurTuner, sizeof(builder_tuner_t));
					stBuilderCtrl.m_u32DataOK = 1;
				}
			}
			else
			{
				PluginDvbLogcat("PluginManualSearchHandleDataRecved() - get section control process not OK\r\n");
			}
		}
		else
		{
			PluginDvbLogcat("PluginManualSearchHandleDataRecved() - send to section control not OK\r\n");
			s32Ret = 0;
		}
	}
	PluginDvbLogcat("PluginManualSearchHandleDataRecved() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginGetNitStreamCount(builder_section_t* m_pstSections, unsigned int* pu32Cnt)
{
	int s32Ret = -1;
	//builder_network_search_control_t* pstCtrl;
	builder_section_t* pstSection;

	PluginDvbLogcat("PluginGetNitStreamCount() - entry, pu32Cnt = %p\r\n", pu32Cnt);
	if(pu32Cnt)
	{
		*pu32Cnt = 0;
		//pstCtrl = &stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl;
		pstSection = m_pstSections;
		while(pstSection)
		{
			*pu32Cnt += SiPsiNITGetTSCount(pstSection->m_au8Section);
			PluginDvbLogcat("PluginGetNitStreamCount() - SiPsiNITGetTSCount, *pu32Cnt = %d\r\n", *pu32Cnt);
			pstSection = pstSection->m_pstNext;
			PluginDvbLogcat("PluginGetNitStreamCount()  pstSection = %p\r\n", pstSection);
		}
		s32Ret = 0;
	}
	PluginDvbLogcat("PluginGetNitStreamCount() - return, pu32Cnt = %d\r\n", *pu32Cnt);
	PluginDvbLogcat("PluginGetNitStreamCount() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginGetNitStreamParam(builder_section_t* m_pstSections, unsigned int u32Index, builder_tuner_t* pstTunerInfo)
{
	int s32Ret = -1;
	builder_network_search_control_t* pstCtrl;
	builder_section_t* pstSection;
	unsigned int u32Cnt = 0;
	unsigned int u32CurSectionTsCnt;
	sipsi_dvb_stream_t stStream;
	sipsi_cable_tunerinfo_t stCableTunerInfo;

	PluginDvbLogcat("PluginGetNitStreamParam() - entry, u32Index = %d, pstTunerInfo = %p\r\n", u32Index, pstTunerInfo);
	if(m_pstSections && pstTunerInfo)
	{
		pstSection = m_pstSections;
		while(pstSection)
		{
			u32CurSectionTsCnt = SiPsiNITGetTSCount(pstSection->m_au8Section);
			if((u32Cnt+u32CurSectionTsCnt) <= u32Index)	////turn to next section
			{
				pstSection = pstSection->m_pstNext;
				u32Cnt += u32CurSectionTsCnt;
			}
			else
			{
				break;
			}
		}
		if(pstSection && u32Index >= u32Cnt)
		{
			u32Index -= u32Cnt;
			SiPsiNITGetTsStream(pstSection->m_au8Section, &stStream, u32Index);
			s32Ret = SiPsiNITGetDeliveryTuneInfo(&stStream, &stCableTunerInfo);	////one ts information
			PluginDvbLogcat("SiPsiNITGetDeliveryTuneInfo() - return, s32Ret = %d\r\n", s32Ret);
			if(s32Ret == 0)
			{
				pstTunerInfo->m_u32Freq = stCableTunerInfo.m_u32Frequency;
				pstTunerInfo->m_u32Mod = stCableTunerInfo.m_u32Modulation;
				pstTunerInfo->m_u32Sym = stCableTunerInfo.m_u32SymbolRate;
				pstTunerInfo->m_u32Bandwidth = 8;
				pstTunerInfo->m_u32Tunertype = BUILDER_TUNER_DVBC;
				PluginDvbLogcat("PluginGetNitStreamParam() - return, pstTunerInfo->m_u32Freq = %d\r\n", pstTunerInfo->m_u32Freq);
				PluginDvbLogcat("PluginGetNitStreamParam() - return, pstTunerInfo->m_u32Mod = %d\r\n", pstTunerInfo->m_u32Mod);
				PluginDvbLogcat("PluginGetNitStreamParam() - return, pstTunerInfo->m_u32Sym = %d\r\n", pstTunerInfo->m_u32Sym);
			}
			else
			{
				memset(pstTunerInfo, 0, sizeof(builder_tuner_t));
			}
		}
	}
	PluginDvbLogcat("PluginGetNitStreamParam() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginQuickGetTunerList()
{
	int s32Ret = -1;
	unsigned int u32TsCnt;
	unsigned int i;
	
	PluginDvbLogcat("PluginQuickGetTunerList() - entry\r\n");
	s32Ret = PluginGetNitStreamCount(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstSections, &u32TsCnt);
	if(s32Ret == 0 && u32TsCnt>0)
	{
		stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total = u32TsCnt;
		stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList = PluginDvbMemAlloc(u32TsCnt*sizeof(builder_tuner_t));
		if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList)
		{
			for(i=0; i<u32TsCnt; i++)
				PluginGetNitStreamParam(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstSections, i, &stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList[i]);
			PluginCheckTunerList(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList, &u32TsCnt);
			stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total = u32TsCnt;
		}
		else
		{
			PluginDvbLogcat("PluginQuickGetTunerList() - malloc error\r\n");
		}
	}
	else
	{
		PluginDvbLogcat("PluginQuickGetTunerList() - get Nit stream count error\r\n");
	}
	PluginDvbLogcat("PluginQuickGetTunerList() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginQuickSearchEnterFreqLoop()
{
	int s32Ret = -1;

	PluginDvbLogcat("PluginQuickSearchEnterFreqLoop() - entry.\r\n");
	
	stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index = 0;
	stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total = 0;
	PluginQuickGetTunerList();
	if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total > 0)
	{
		memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList[0], sizeof(builder_tuner_t));
		s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
		stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus = BUILDER_NETWORT_SEARCH_FREQ_LOOP;
		stBuilderCtrl.m_u32DataOK = 1;
		stBuilderCtrl.m_u32Process = (QUICK_SCAN_NIT_PROCESS+QUICK_SCAN_LOCK_PROCESS);//nit ok 4%
		stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
	}
	else
	{
		//PluginQuickFreeNit();
		PluginDvbMemFree(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList);
		stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList = NULL;
		stBuilderCtrl.m_u32DataOK = 1;
		stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
		s32Ret = -1;
	}
	PluginDvbLogcat("PluginQuickSearchEnterFreqLoop() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginQuickSearchAddNit(unsigned char* pu8Data)
{
	int s32Ret = -1;
	builder_section_t* pstSection;
	builder_section_t* pstTmpSection;
	builder_section_t* pstTmpPrevSection;
	unsigned char u8SectionNum;

	PluginDvbLogcat("PluginQuickSearchAddNit() - entry.\r\n");
	pstSection = NULL;
	PluginCreatSectionNode(&pstSection, pu8Data);
	u8SectionNum = SiPsiGetSectionNo(pu8Data);
	pstTmpPrevSection = stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstSections;
	if(pstTmpPrevSection && SiPsiGetSectionNo(pstTmpPrevSection->m_au8Section)<u8SectionNum)
	{
		s32Ret = 0;
		pstTmpSection = pstTmpPrevSection->m_pstNext;
		while(pstTmpSection)
		{
			if(SiPsiGetSectionNo(pstTmpSection->m_au8Section)>u8SectionNum)
				break;
			pstTmpPrevSection = pstTmpSection;
			pstTmpSection = pstTmpPrevSection->m_pstNext;
		}
		pstSection->m_pstNext = pstTmpSection;
		pstTmpPrevSection->m_pstNext = pstSection;
	}
	else
	{
		s32Ret = 0;
		pstSection->m_pstNext = stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstSections;
		stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstSections = pstSection;
	}
	PluginDvbLogcat("PluginQuickSearchAddNit() - return, s32Ret = %d\r\n", s32Ret);

	return s32Ret;
}

int PluginQuickSearchHandleDataRecved(unsigned char* pu8Data, unsigned int hFilter)
{
	int s32Ret = -1;
	unsigned char u8SectionNum;
	unsigned char u8LastSectionNum;
	unsigned int u32Process;

	PluginDvbLogcat("PluginQuickSearchHandleDataRecved() - entry, pu8Data = %p, hFilter = %x\r\n", pu8Data, hFilter);
	if(pu8Data)
	{
		if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus == BUILDER_NETWORT_SEARCH_RECV_NIT)
		{
			stBuilderCtrl.m_u32TimeOut = 5;
			if(pu8Data[0] == SIPSI_TID_NIT_ACTUAL)
			{
				stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32RecvDataTimes++;
				u8SectionNum = SiPsiGetSectionNo(pu8Data);
				u8LastSectionNum = SiPsiGetLastSectionNo(pu8Data);
				PluginDvbLogcat("PluginQuickSearchHandleDataRecved() - u8SectionNum = %x\r\n", u8SectionNum);
				PluginDvbLogcat("PluginQuickSearchHandleDataRecved() - u8LastSectionNum = %x\r\n", u8LastSectionNum);
				
				s32Ret = 0;
				if(PluginSecRecvCheck(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_au8SecRecvBitmap, u8SectionNum)!=0)
				{
					PluginQuickSearchAddNit(pu8Data);
					if(PluginSecFinishCheck(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_au8SecRecvBitmap, u8LastSectionNum, u8SectionNum) == 0)
					{
						PluginRecvNitStop();
						s32Ret = PluginQuickSearchEnterFreqLoop();
					}
				}
				else if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32RecvDataTimes > (u8LastSectionNum+1)*2)
				{
					PluginRecvNitStop();
					s32Ret = PluginQuickSearchEnterFreqLoop();
				}
			}
			else
			{
				PluginDvbLogcat("PluginQuickSearchHandleDataRecved() - table id is not SIPSI_TID_NIT_ACTUAL\r\n");
				PluginRecvNitStop();
				PluginQuickFreeNit();
				s32Ret = -1;
			}
		}
		else if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus == BUILDER_NETWORT_SEARCH_FREQ_LOOP)
		{
			stBuilderCtrl.m_u32TimeOut = 4;
			s32Ret = PluginSectionDataRecv(&stBuilderCtrl.m_stSecCtrl, hFilter, pu8Data);
			if(s32Ret == 0)
			{
				s32Ret = PluginSectionDataGetProcess(&stBuilderCtrl.m_stSecCtrl, &u32Process);
				if(s32Ret == 0)
				{
					stBuilderCtrl.m_u32Process = (QUICK_SCAN_NIT_PROCESS+QUICK_SCAN_LOCK_PROCESS) +  QUICK_SCAN_SIPSI_PROCESS*stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index/stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total +(QUICK_SCAN_SIPSI_PROCESS*u32Process/stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total/SCAN_ALL_PROCESS);//section control 96%, tuner lock 2%, nit recv 2%
					PluginDvbLogcat("PluginQuickSearchHandleDataRecved() - cur freq process %d, stBuilderCtrl.m_u32Process = %d, [%d/%d]\r\n", u32Process, stBuilderCtrl.m_u32Process, stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index, stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total);
					if(u32Process == SCAN_ALL_PROCESS)
					{
						stBuilderCtrl.m_u32DataOK = 1;
						stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index++;
						memcpy(&stBuilderCtrl.m_stDataOkTunerInfo, &stBuilderCtrl.m_stCurTuner, sizeof(builder_tuner_t));
						if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index < stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total)
						{
							memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index], sizeof(builder_tuner_t));
							PluginDvbLogcat("PluginQuickSearchHandleDataRecved() - start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
							s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
							stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
						}
						else
						{
							stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
							stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
						}
					}
				}
				else
				{
					PluginDvbLogcat("PluginQuickSearchHandleDataRecved() - get section control process not OK\r\n");
				}
			}
			else
			{
				//PluginSectionDataReset(&stBuilderCtrl.m_stSecCtrl);
				PluginDvbLogcat("PluginQuickSearchHandleDataRecved() - send to section control not OK\r\n");
				s32Ret = 0;
			}

		}
	}
	PluginDvbLogcat("PluginQuickSearchHandleDataRecved() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginFullSearchHandleDataRecved(unsigned char* pu8Data, unsigned int hFilter)
{
	int s32Ret = -1;
	unsigned int u32Process;

	PluginDvbLogcat("PluginFullSearchHandleDataRecved() - entry, pu8Data = %p, hFilter = %x\r\n", pu8Data, hFilter);
	if(pu8Data)
	{
		s32Ret = PluginSectionDataRecv(&stBuilderCtrl.m_stSecCtrl, hFilter, pu8Data);
		if(s32Ret == 0)
		{
			s32Ret = PluginSectionDataGetProcess(&stBuilderCtrl.m_stSecCtrl, &u32Process);
			if(s32Ret == 0)
			{
				PluginSearchSetProcess(0, SCAN_ALL_PROCESS, u32Process);

				if(u32Process == SCAN_ALL_PROCESS)
				{
					stBuilderCtrl.m_u32DataOK = 1;
					stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32Index++;
					memcpy(&stBuilderCtrl.m_stDataOkTunerInfo, &stBuilderCtrl.m_stCurTuner, sizeof(builder_tuner_t));
					if(stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32Index <= stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32EndIndex)
					{
						memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32Index], sizeof(builder_tuner_t));
						PluginDvbLogcat("PluginFullSearchHandleDataRecved() - start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
						s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;	
					}
					else
					{
						PluginDvbLogcat("PluginFullSearchHandleDataRecved() - all freq index end [%d~%d]\r\n", stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32StartIndex, stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32EndIndex);
						stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
					}
				}
			}
			else
			{
				PluginDvbLogcat("PluginFullSearchHandleDataRecved() - get section control process not OK\r\n");
			}
		}
		else
		{
			//PluginSectionDataReset(&stBuilderCtrl.m_stSecCtrl);
			PluginDvbLogcat("PluginFullSearchHandleDataRecved() - send to section control not OK\r\n");
			s32Ret = 0;
		}
	}

	PluginDvbLogcat("PluginFullSearchHandleDataRecved() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginAutoGetTunerList()
{
	int s32Ret = -1;
	unsigned int u32TsCnt;
	unsigned int i;
	
	PluginDvbLogcat("PluginAutoGetTunerList() - entry\r\n");
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex = 0;
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex   = 0;
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index = 0;
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total = 0;
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList = NULL;
	s32Ret = PluginGetNitStreamCount(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections, &u32TsCnt);
	if(s32Ret == 0 && u32TsCnt>0)
	{
		stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total = u32TsCnt;
		stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex = u32TsCnt - 1;
		stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList = PluginDvbMemAlloc(u32TsCnt*sizeof(builder_tuner_t));
		if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList)
		{
			for(i=0; i<u32TsCnt; i++)
				PluginGetNitStreamParam(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections, i, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[i]);
			PluginCheckTunerList(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList, &u32TsCnt);
			stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total = u32TsCnt;
			stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex = u32TsCnt - 1;
		}
		else
		{
			PluginDvbLogcat("PluginAutoGetTunerList() - malloc error\r\n");
			stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index = 0;
			stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total = 0;
		}
	}
	else
	{
		PluginDvbLogcat("PluginAutoGetTunerList() - get Nit stream count error\r\n");
	}
	PluginDvbLogcat("PluginAutoGetTunerList() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginAutoSearchAddNit(unsigned char* pu8Data)
{
	int s32Ret = -1;
	builder_section_t* pstSection;
	builder_section_t* pstTmpSection;
	builder_section_t* pstTmpPrevSection;
	unsigned char u8SectionNum;

	PluginDvbLogcat("PluginAutoSearchAddNit() - entry.\r\n");
	pstSection = NULL;
	PluginCreatSectionNode(&pstSection, pu8Data);
	u8SectionNum = SiPsiGetSectionNo(pu8Data);
	pstTmpPrevSection = stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections;
	if(pstTmpPrevSection && SiPsiGetSectionNo(pstTmpPrevSection->m_au8Section)<u8SectionNum)
	{
		pstTmpSection = pstTmpPrevSection->m_pstNext;
		while(pstTmpSection)
		{
			if(SiPsiGetSectionNo(pstTmpSection->m_au8Section)>u8SectionNum)
				break;
			pstTmpPrevSection = pstTmpSection;
			pstTmpSection = pstTmpPrevSection->m_pstNext;
		}
		pstSection->m_pstNext = pstTmpSection;
		pstTmpPrevSection->m_pstNext = pstSection;
	}
	else
	{
		pstSection->m_pstNext = stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections;
		stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections = pstSection;
	}
	PluginDvbLogcat("PluginAutoSearchAddNit() - return, s32Ret = %d\r\n", s32Ret);

	return s32Ret;
}

int PluginAutoSearchEnterFullFreqLoop()
{
	int s32Ret = -1;
	unsigned int u32FreqCnt;

	PluginDvbLogcat("PluginAutoSearchEnterFullFreqLoop() - entry.\r\n");
	u32FreqCnt = 0;
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus = BUILDER_AUTO_SEARCH_FULL_FREQ_LOOP;
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList = PluginGetFreqTable(&u32FreqCnt);
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex = 0;
	stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex = u32FreqCnt - 1;
	if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex > stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex)
	{
		stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index = stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex;
		memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex], sizeof(builder_tuner_t));
		s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
		stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
		stBuilderCtrl.m_u32DataOK = 1;
		stBuilderCtrl.m_u32Process = AUTO_SCAN_NIT_PROCESS;//nit ok 10%
	}
	else
	{
		stBuilderCtrl.m_u32DataOK = 0;
		stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
		s32Ret = -1;
	}
	PluginDvbLogcat("PluginAutoSearchEnterFullFreqLoop() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginAutoSearchEnterNitFreqLoop()
{
	int s32Ret = -1;

	PluginDvbLogcat("PluginAutoSearchEnterNitFreqLoop() - entry.\r\n");
	PluginAutoGetTunerList();
	if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total > 0)
	{
		memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[0], sizeof(builder_tuner_t));
		s32Ret  = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
		
		stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus = BUILDER_AUTO_SEARCH_NIT_FREQ_LOOP;
		stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
		stBuilderCtrl.m_u32DataOK = 1;
		stBuilderCtrl.m_u32Process = AUTO_SCAN_NIT_PROCESS;//nit ok 10%
	}
	else
	{
		PluginDvbMemFree(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList);
		stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList = NULL;
		stBuilderCtrl.m_u32DataOK = 1;//NIT ok
		s32Ret = PluginAutoSearchEnterFullFreqLoop();
	}
	PluginDvbLogcat("PluginAutoSearchEnterNitFreqLoop() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginAutoSearchHandleDataRecved(unsigned char* pu8Data, unsigned int hFilter)
{
	int s32Ret = -1;
	unsigned char u8SectionNum;
	unsigned char u8LastSectionNum;
	unsigned int u32Process = 0;
	unsigned char u8BatSectionNum;
	unsigned char u8BatLastSectionNum;
	
	PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - entry, pu8Data = %p, hFilter = %x\r\n", pu8Data, hFilter);
	if(pu8Data)
	{
		s32Ret = 0;
		switch(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus)
		{
			case BUILDER_AUTO_SEARCH_SCAN_NIT:
			{
				stBuilderCtrl.m_u32TimeOut = 10;
				if(pu8Data[0] == SIPSI_TID_NIT_ACTUAL)
				{
					stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32RecvDataTimes++;
					u8SectionNum = SiPsiGetSectionNo(pu8Data);
					u8LastSectionNum = SiPsiGetLastSectionNo(pu8Data);
					PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - u8SectionNum = %x\r\n", u8SectionNum);
					PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - u8LastSectionNum = %x\r\n", u8LastSectionNum);
					s32Ret = 0;
					
					if(PluginSecRecvCheck(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_au8SecRecvBitmap, u8SectionNum)!=0)
					{
						unsigned int m_u32PreProcess = (AUTO_SCAN_NIT_PROCESS-2)*(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index - stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex + 1)/(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex - stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex + 1);//scan nit and bat 10%
						unsigned int m_u32RecCount = PluginSecRecvCount(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_au8SecRecvBitmap, u8LastSectionNum);
						stBuilderCtrl.m_u32Process = m_u32PreProcess + (AUTO_SCAN_NIT_PROCESS-2-m_u32PreProcess)*m_u32RecCount/(u8LastSectionNum+1);	//scan nit 8% bat 2%
						PluginAutoSearchAddNit(pu8Data);
						
						if(PluginSecFinishCheck(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_au8SecRecvBitmap, u8LastSectionNum, u8SectionNum) == 0)
						{
							PluginRecvNitStop();
							s32Ret = PluginAutoSearchEnterNitFreqLoop();
						}
					}
					else if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32RecvDataTimes > (u8LastSectionNum+1)*2)
					{
						PluginRecvNitStop();
						s32Ret = PluginAutoSearchEnterNitFreqLoop();
					}
				}
				
				break;
			}
			case BUILDER_AUTO_SEARCH_NIT_FREQ_LOOP:
			{
				stBuilderCtrl.m_u32TimeOut = 4;
				s32Ret = PluginSectionDataRecv(&stBuilderCtrl.m_stSecCtrl, hFilter, pu8Data);
				if(s32Ret == 0)
				{
					s32Ret = PluginSectionDataGetProcess(&stBuilderCtrl.m_stSecCtrl, &u32Process);
					if(s32Ret == 0)
					{
						PluginSearchSetProcess(AUTO_SCAN_NIT_PROCESS, AUTO_SCAN_SIPSI_PROCESS, u32Process);

						PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - cur freq process %d, stBuilderCtrl.m_u32Process = %d, [%d/%d]\r\n", u32Process, stBuilderCtrl.m_u32Process, stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index, stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total);
						if(u32Process == SCAN_ALL_PROCESS)
						{
							stBuilderCtrl.m_u32DataOK = 1;
							stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index++;
							memcpy(&stBuilderCtrl.m_stDataOkTunerInfo, &stBuilderCtrl.m_stCurTuner, sizeof(builder_tuner_t));
							if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total > stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index)
							{
								memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index], sizeof(builder_tuner_t));
								PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
								s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
								stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
							}
							else
							{
								stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
								stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
							}
						}
					}
					else
					{
						PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - get section control process not OK, maybe section have received\r\n");
					}
				}
				else
				{
					PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - get section control process not OK, maybe section have received\r\n");
					s32Ret = 0;
				}
				break;
			}
			case BUILDER_AUTO_SEARCH_FULL_FREQ_LOOP:
			{
				s32Ret = PluginSectionDataRecv(&stBuilderCtrl.m_stSecCtrl, hFilter, pu8Data);
				if(s32Ret == 0)
				{
					s32Ret = PluginSectionDataGetProcess(&stBuilderCtrl.m_stSecCtrl, &u32Process);
					if(s32Ret == 0)
					{
						PluginSearchSetProcess(AUTO_SCAN_NIT_PROCESS, AUTO_SCAN_SIPSI_PROCESS, u32Process);

						if(u32Process == SCAN_ALL_PROCESS)
						{
							stBuilderCtrl.m_u32DataOK = 1;
							stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index++;
							memcpy(&stBuilderCtrl.m_stDataOkTunerInfo, &stBuilderCtrl.m_stCurTuner, sizeof(builder_tuner_t));
							if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index <= stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex)
							{
								memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index], sizeof(builder_tuner_t));
								PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
								s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
								stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;	
							}
							else
							{
								PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - all freq index end [%d~%d]\r\n", stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex, stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex);
								stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
							}
						}
					}
					else
					{
						PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - get section control process not OK\r\n");
						s32Ret = 0;
					}
				}
				else
				{
					PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - send to section control not OK\r\n");
				}
				break;
			}
			default:
			{
				PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - status error stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus = %d\r\n", stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus);
				break;
			}
		}
	}
	PluginDvbLogcat("PluginAutoSearchHandleDataRecved() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginBootUpdateHandleDataRecved(unsigned char* pu8Data, unsigned int hFilter)
{
	int s32Ret = -1;

	PluginDvbLogcat("PluginBootUpdateHandleDataRecved() - entry, pu8Data = %p, hFilter = %x\r\n", pu8Data, hFilter);
	
	PluginDvbLogcat("PluginBootUpdateHandleDataRecved() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}


int PluginDataRecved(unsigned int hFilter, unsigned char* pu8Data, unsigned int u32Len)
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginDataRecved() - entry, hFilter = %x, pu8Data = %p, u32Len = %d\r\n", hFilter, pu8Data, u32Len);
	PluginDvbLogcat("PluginDataRecved() - stBuilderCtrl.m_eStatus = %d\r\n", stBuilderCtrl.m_eStatus);
	if(stBuilderCtrl.m_eStatus==BUILDER_PLUGIN_RECV_SIPSI)
	{			
		switch(stBuilderCtrl.m_eSearchType)
		{
			case BUILDER_SEARCH_MANUAL_SEARCH:
			{
				s32Ret = PluginManualSearchHandleDataRecved(pu8Data, hFilter);
				break;
			}
			case BUILDER_SEARCH_NETWORK_SEARCH:
			{
				s32Ret = PluginQuickSearchHandleDataRecved(pu8Data, hFilter);
				break;
			}
			case BUILDER_SEARCH_FULL_SEARCH:
			{
				s32Ret = PluginFullSearchHandleDataRecved(pu8Data, hFilter);
				break;
			}
			case BUILDER_SEARCH_AUTO_SEARCH:
			{
				s32Ret = PluginAutoSearchHandleDataRecved(pu8Data, hFilter);
				break;
			}
			case BUILDER_SEARCH_BOOT_UPDATE:
			{
				s32Ret = PluginBootUpdateHandleDataRecved(pu8Data, hFilter);
				break;
			}
			case BUILDER_SEARCH_MONITOR_SEARCH:
			{
				s32Ret = PluginMonitorSearchHandleDataRecved(pu8Data, hFilter);
				break;
			}
			default:
			{
				break;
			}
		}
	}
	else if(stBuilderCtrl.m_eStatus==BUILDER_PLUGIN_WAITE_TUNER_LOCK )
	{
		PluginDvbLogcat("PluginDataRecved() - while status is tuner lock\r\n");
		s32Ret = 0;
	}
	PluginDvbLogcat("PluginDataRecved() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
}

int PluginGetSearchData(builder_ts_t* pstTs, builder_service_t* pstServices, unsigned int* pu32ServiceCnt, builder_section_t** ppstBat, builder_section_t** ppstNit)
{
	int s32Ret = -1;
	builder_ts_t stTs;
	builder_service_t astServices[BUILDER_MAX_PROG_PER_TS];
	unsigned int u32ServiceCnt = 0;
	
	PluginDvbLogcat("PluginGetSearchData() - entry, pstTs = %p, pstServices = %p, pu32ServiceCnt = %p, pstBat = %p, pstNit = %p\r\n", pstTs, pstServices, pu32ServiceCnt, ppstBat, ppstNit);
	if(stBuilderCtrl.m_u32DataOK == 1)
	{
		memset(&stTs, 0, sizeof(stTs));
		s32Ret = PluginSectionDataGetSections(&stBuilderCtrl.m_stSecCtrl, &stTs.m_stSiPsi);
		if(s32Ret == 0)
		{
			if(stTs.m_stSiPsi.m_pstPat && stTs.m_stSiPsi.m_pstPmt)
			{
				memcpy(&stTs.m_stTuner, &stBuilderCtrl.m_stDataOkTunerInfo, sizeof(stTs.m_stTuner));
				s32Ret = PluginParseTs(&stTs, astServices, &u32ServiceCnt);

				if(s32Ret == 0)
				{
					memcpy(pstTs, &stTs, sizeof(stTs));
					*pu32ServiceCnt = u32ServiceCnt;
					memcpy(pstServices, astServices, u32ServiceCnt*sizeof(builder_service_t));
				}
				else
					PluginDvbLogcat("PluginGetSearchData() - PluginParseTs error\r\n");
			}
		}
		
		if(stBuilderCtrl.m_eSearchType == BUILDER_SEARCH_NETWORK_SEARCH)
		{
			*ppstNit = stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstSections;
			stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstSections = NULL;
		}
		else if(stBuilderCtrl.m_eSearchType == BUILDER_SEARCH_AUTO_SEARCH)
		{
			*ppstNit = stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections;
			stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstSections = NULL;
			if (NULL != stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstBatSections)
				*ppstBat = stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstBatSections;
			stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstBatSections = NULL;
		}
		
		//*ppstBat = NULL;
		stBuilderCtrl.m_u32DataOK = 0;
	}
	PluginDvbLogcat("PluginGetSearchData() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
}

void PluginSwap(builder_service_t* a, builder_service_t* b)
{
	builder_service_t tmp;
	memcpy(&tmp, a, sizeof(builder_service_t));
	memcpy(a, b, sizeof(builder_service_t));
	memcpy(b, &tmp, sizeof(builder_service_t));
}


int PluginPartition(builder_service_t* pstServices, int low, int high)
{
	unsigned short KeyLcn = pstServices[low].m_u16Lcn;
	PluginDvbLogcat("PluginPartition() - entry, low=%d, high=%d\r\n", low,high);
	while (low < high && low>=0 && high>=0) {
		PluginDvbLogcat("PluginPartition() - , low=%d, high=%d, pstServices[high].m_u16Lcn=%d,pstServices[low].m_u16Lcn=%d\r\n", low,high, pstServices[high].m_u16Lcn,pstServices[low].m_u16Lcn);

		while (low < high && pstServices[high].m_u16Lcn >= KeyLcn) {
			--high;
		}
		PluginSwap(&pstServices[low],&pstServices[high]);

		while (low < high && pstServices[low].m_u16Lcn <= KeyLcn) {
			++low;
		}
		PluginSwap(&pstServices[low],&pstServices[high]);

	}

	return low;
}

int PluginQuickSortByLcn(builder_service_t* pstServices, int low, int high)
{
	PluginDvbLogcat("PluginQuickSortByLcn() - entry, low=%d, high=%d\r\n", low,high);

	if (low < high && low>=0 && high>=0) {
		int PreLow = PluginPartition(pstServices,low, high);
		PluginDvbLogcat("PluginQuickSortByLcn() PreLow=%d\r\n", PreLow);
		if (PreLow >= 0) {
			PluginQuickSortByLcn(pstServices, low, PreLow-1);
			PluginQuickSortByLcn(pstServices, PreLow+1, high);
		}
	}

	return 0;
}

int PluginRemoveIllegalLcn(builder_service_t* pstServices, unsigned int* pu32ServiceCnt)
{
	int i = 0,j = 0;
	unsigned int u32Jump = 0;

	for(i=0; i<*pu32ServiceCnt; i++)
	{
		if(pstServices[i].m_u16Lcn == 0 || pstServices[i].m_eType == BUILDER_SERVICE_DATABROCAST
			|| pstServices[i].m_eType == BUILDER_SERVICE_RADIO || pstServices[i].m_eType == BUILDER_SERVICE_UNKNOWN)
		{
			PluginDvbLogcat("PluginRemoveIllegalLcn() - need delete this service, service id[%d], freq[%d]\r\n", pstServices[i].m_u16Serviceid, pstServices[i].m_u32Freq);
			u32Jump++;
		}
		else if(u32Jump > 0)
		{
			memcpy(&(pstServices[i - u32Jump]), &(pstServices[i]), sizeof(builder_service_t));
		}
	}
	*pu32ServiceCnt = *pu32ServiceCnt - u32Jump;

	return 0;
}

int PluginSortByServiceId(builder_service_t* pstServices,  unsigned int* pu32ServiceCnt)
{
	unsigned int u32Index;
	int s32Ret = -1;
	unsigned int i;
	unsigned int j;
	builder_service_t curServiceData;
	builder_service_t tmpServiceData;
	unsigned short u16CurServiceid;
	unsigned short u16MinServiceid;
	
	PluginDvbLogcat("PluginSortByServiceId() - entry, pstServices = %d, pu32ServiceCnt = %p\r\n", pstServices, pu32ServiceCnt);
	if(pstServices && pu32ServiceCnt)
	{
		for(i=0; i<*pu32ServiceCnt;i++)
		{
			u16MinServiceid = 0;
			for(j=i; j<*pu32ServiceCnt; j++)
			{
				curServiceData = pstServices[j];
				u16CurServiceid = curServiceData.m_u16Serviceid;
				if(!u16MinServiceid || u16MinServiceid>u16CurServiceid)
				{
					u16MinServiceid = u16CurServiceid;
					u32Index = j;	
				}
			}
			if(u32Index != i)
			{
				tmpServiceData = pstServices[u32Index];
				pstServices[u32Index] = pstServices[i];
				pstServices[i] = tmpServiceData;
			}
		}
		s32Ret = 0;
	}
	PluginDvbLogcat("PluginSortByServiceId() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}


int PluginProgSort(builder_ts_t* pstTsList, builder_service_t* pstServices, unsigned int* pu32ServiceCnt, builder_section_t* pstBat, builder_section_t* pstNit)
{
	int s32Ret = -1;
	char su8TmpArray[100];
	unsigned int i;
	
	PluginDvbLogcat("PluginProgSort() - entry, pstTsList = %d, pstServices = %p, pu32ServiceCnt = %d, pstBat = %p, pstNit = %p\r\n", pstTsList, pstServices, *pu32ServiceCnt, pstBat, pstNit);
	for(i=0; i<*pu32ServiceCnt; i++)
	{
		PluginDvbLogcat("PluginProgSort() - i[%d], Lcn[%d], Fre[%d], Tsid[%d], Sid[%d], Name[%s]\r\n", i, pstServices[i].m_u16Lcn,
			pstServices[i].m_u32Freq, pstServices[i].m_u16Tsid, pstServices[i].m_u16Serviceid, pstServices[i].m_as8Name);

	}

	if (stBuilderCtrl.m_eSearchType == BUILDER_SEARCH_AUTO_SEARCH)
	{
		PluginDvbLogcat("PluginProgSort() - ato search!\r\n");
		s32Ret = 1;
		PluginRemoveIllegalLcn(pstServices, pu32ServiceCnt);
		PluginQuickSortByLcn(pstServices, 0, (int)*pu32ServiceCnt-1);

	} else{
		PluginDvbLogcat("PluginProgSort() - sigle search!\r\n");
		s32Ret = 0;
		PluginSortByServiceId(pstServices, pu32ServiceCnt);
	}
		
	for(i=0; i<*pu32ServiceCnt; i++)
	{
		memset(su8TmpArray, 0, sizeof(su8TmpArray));
		memcpy(su8TmpArray, pstServices[i].m_as8Name, pstServices[i].m_u16NameLen);
		PluginDvbConvertString(su8TmpArray, pstServices[i].m_u16NameLen, NULL);
		PluginDvbLogcat("PluginProgSort() - i[%d], Fre[%d], Tsid[%d], Sid[%d], Name[%s]\r\n", i, 
			pstServices[i].m_u32Freq, pstServices[i].m_u16Tsid, pstServices[i].m_u16Serviceid, su8TmpArray);
	}
	PluginDvbLogcat("PluginProgSort() - return, s32Ret = %d\r\n", s32Ret);
	
	return s32Ret;	
}

static int PluginMonitorFreeNit()
{
	int s32Ret = -0;

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorFreeNit() - entry, pstSection = %p\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstNitSections);

	if(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstNitSections)
	{
		s32Ret = PluginFreeTable(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstNitSections);
		stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstNitSections = NULL;
	}

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorFreeNit() - return, s32Ret = %d\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId, s32Ret);
	return s32Ret;
}

int PluginMonitorSearchAddNit(unsigned char* pu8Data)
{
	int s32Ret = 0;
	builder_section_t* pstSection = NULL;
	builder_section_t* pstTmpSection;
	builder_section_t* pstTmpPrevSection;
	unsigned char u8SectionNum;

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchAddNit() - entry.\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
	PluginCreatSectionNode(&pstSection, pu8Data);
	u8SectionNum = SiPsiGetSectionNo(pu8Data);
	pstTmpPrevSection = stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstNitSections;
	if(pstTmpPrevSection && SiPsiGetSectionNo(pstTmpPrevSection->m_au8Section)<u8SectionNum)
	{
		pstTmpSection = pstTmpPrevSection->m_pstNext;
		while(pstTmpSection)
		{
			if(SiPsiGetSectionNo(pstTmpSection->m_au8Section)>u8SectionNum)
				break;
			pstTmpPrevSection = pstTmpSection;
			pstTmpSection	  = pstTmpPrevSection->m_pstNext;
		}
		pstSection->m_pstNext = pstTmpSection;
		pstTmpPrevSection->m_pstNext = pstSection;
	}
	else
	{
		pstSection->m_pstNext = stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstNitSections;
		stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstNitSections = pstSection;
	}
	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchAddNit() - return, s32Ret = %d\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,s32Ret);

	return s32Ret;
}

int PluginMonitorSearchHandleRecvNit(unsigned char *pu8Data)
{
	int s32Ret = 0;
	unsigned char u8SectionNum;
	unsigned char u8LastSectionNum;
	unsigned int  u32Crc;
	unsigned short u16TableID;

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvNit enter!\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
	u16TableID = SiPsiGetTableID(pu8Data);
	if(u16TableID == SIPSI_TID_NIT_ACTUAL)
	{
		u8SectionNum	 = SiPsiGetSectionNo(pu8Data);
		u8LastSectionNum = SiPsiGetLastSectionNo(pu8Data);
		u32Crc			 = SiPsiGetSectionCrc(pu8Data);
		PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvNit() - SectionNum[%d],LastSectionNum[%d], CRC[0x%x]\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,u8SectionNum,u8LastSectionNum,u32Crc);

		if(PluginSecRecvCheck(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap, u8SectionNum)!=0)
		{
			PluginMonitorSearchAddNit(pu8Data);
			if(PluginSecFinishCheck(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap, u8LastSectionNum, u8SectionNum) == 0)
			{
				PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvNit:recv nit finish!\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
				PluginRecvNitStop();
				memset(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap, 0, sizeof(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap));
				stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvDataTimes = 0;
				stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_eStatus = BUILDER_MONITOR_SEARCH_RECV_PSI;
				stBuilderCtrl.m_u32TimeOut = 4;
				PluginSectionDataStart(&stBuilderCtrl.m_stSecCtrl);
			}
		}

		if(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvDataTimes++ > (u8LastSectionNum+1)*2)
		{
			PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvNit:recv nit not complete!\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
			PluginRecvNitStop();
			memset(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap, 0, sizeof(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap));
			stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvDataTimes = 0;
			stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_eStatus = BUILDER_MONITOR_SEARCH_RECV_PSI;
			stBuilderCtrl.m_u32TimeOut = 4;
			PluginSectionDataStart(&stBuilderCtrl.m_stSecCtrl);
		}
	}
	else
	{
		PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvNit() - table id = 0x%x is not SIPSI_TID_NIT_ACTUAL\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,u16TableID);
		s32Ret = -1;
	}
	return s32Ret;
}

static int PluginMonitorFreeBat()
{
	int s32Ret = -0;

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorFreeBat() - entry, pstSection = %p\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstBatSections);

	if(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstBatSections)
	{
		s32Ret = PluginFreeTable(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstBatSections);
		stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstBatSections = NULL;
	}

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorFreeBat() - return, s32Ret = %d\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,s32Ret);
	return s32Ret;
}

int PluginMonitorSearchAddBat(unsigned char* pu8Data)
{
	int s32Ret = 0;
	builder_section_t* pstSection = NULL;
	builder_section_t* pstTmpSection;
	builder_section_t* pstTmpPrevSection;
	unsigned char u8SectionNum;

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchAddBat() - entry.\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
	PluginCreatSectionNode(&pstSection, pu8Data);
	u8SectionNum = SiPsiGetSectionNo(pu8Data);
	pstTmpPrevSection = stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstBatSections;
	if(pstTmpPrevSection && SiPsiGetSectionNo(pstTmpPrevSection->m_au8Section)<u8SectionNum)
	{
		pstTmpSection = pstTmpPrevSection->m_pstNext;
		while(pstTmpSection)
		{
			if(SiPsiGetSectionNo(pstTmpSection->m_au8Section)>u8SectionNum)
				break;
			pstTmpPrevSection = pstTmpSection;
			pstTmpSection = pstTmpPrevSection->m_pstNext;
		}
		pstSection->m_pstNext = pstTmpSection;
		pstTmpPrevSection->m_pstNext = pstSection;
	}
	else
	{
		pstSection->m_pstNext = stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstBatSections;
		stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstBatSections = pstSection;
	}

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchAddBat() - return, s32Ret = %d\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,s32Ret);

	return s32Ret;
}

static int PluginRecvBatStop()
{
	int s32Ret = -1;

	PluginDvbLogcat("PluginRecvBatStop() - entry\r\n");
	if(stBuilderCtrl.m_u32FilterId != BUILDER_INVALID_FILTER)
	{
		s32Ret = PluginDvbReleaseFilter(stBuilderCtrl.m_u32FilterId);
		stBuilderCtrl.m_u32FilterId = BUILDER_INVALID_FILTER;
	}

	PluginDvbLogcat("PluginRecvBatStop() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginMonitorSearchHandleRecvBat(unsigned char *pu8Data)
{
	int s32Ret = 0;
	unsigned char u8SectionNum;
	unsigned char u8LastSectionNum;
	unsigned short u16BouqueID;
	unsigned short u16TableID;
	unsigned int   u32Crc;
	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvBat enter!\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);

	u16TableID = SiPsiGetTableID(pu8Data);
	if(u16TableID == SIPSI_TID_BAT)
	{
		u16BouqueID 	 = SiPsiBATGetBouquetID(pu8Data);
		PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvBat:bouqueID is 0x%x!\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,u16BouqueID);
		if (0x6001 != u16BouqueID && 0x7011 != u16BouqueID)  //24577:���� Cable Network  28689���ϲ� Cable Network
		{
			stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvBatDataTimes++;
			if(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvBatDataTimes > 5)  //����5��û���յ���ȷ��BAT BouqueID
			{
				PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvBat:haven't recv bat!\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
				PluginRecvBatStop();
				memset(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap, 0, sizeof(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap));
				stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvDataTimes = 0;
				stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_eStatus = BUILDER_MONITOR_SEARCH_RECV_PSI;
				stBuilderCtrl.m_u32TimeOut = 4;
				PluginSectionDataStart(&stBuilderCtrl.m_stSecCtrl);
			}
			return -1;
		}

		stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvBatDataTimes = 0;

		u8SectionNum	 = SiPsiGetSectionNo(pu8Data);
		u8LastSectionNum = SiPsiGetLastSectionNo(pu8Data);
		u32Crc			 = SiPsiGetSectionCrc(pu8Data);
		PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvBat() - SectionNum[%d],LastSectionNum[%d], CRC[0x%x]\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,u8SectionNum,u8LastSectionNum, u32Crc);

		if(PluginSecRecvCheck(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap, u8SectionNum)!=0)
		{
			PluginMonitorSearchAddBat(pu8Data);
			if(PluginSecFinishCheck(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap, u8LastSectionNum, u8SectionNum) == 0)
			{
				PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvBat:recv bat finish!\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
				PluginRecvBatStop();
				memset(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap, 0, sizeof(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap));
				stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvDataTimes = 0;
				stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_eStatus = BUILDER_MONITOR_SEARCH_RECV_PSI;
				stBuilderCtrl.m_u32TimeOut = 4;
				PluginSectionDataStart(&stBuilderCtrl.m_stSecCtrl);
			}
		}

		if(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvDataTimes++ > (u8LastSectionNum+1)*2)
		{
			PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvBat:recv bat not complete!\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
			PluginRecvBatStop();
			memset(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap, 0, sizeof(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap));
			stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvDataTimes = 0;
			stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_eStatus = BUILDER_MONITOR_SEARCH_RECV_PSI;
			stBuilderCtrl.m_u32TimeOut = 4;
			PluginSectionDataStart(&stBuilderCtrl.m_stSecCtrl);
		}
	}
	else
	{
		PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleRecvBat() - table id = 0x%x is not SIPSI_TID_BAT\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId, u16TableID);
		s32Ret = -1;
	}
	return s32Ret;
}

int PluginMonitorSearchHandleDataRecved(unsigned char* pu8Data, unsigned int hFilter)
{
	int s32Ret = 0;
	unsigned int u32Process;
	BUILDER_MONITOR_SEARCH_STATUS eMonitorStatus;
	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleDataRecved() - entry, pu8Data = %p, hFilter = %x\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId, pu8Data, hFilter);
	eMonitorStatus = stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_eStatus;
	if(pu8Data)
	{
		if (BUILDER_MONITOR_SEARCH_RECV_NIT == eMonitorStatus)
		{
			stBuilderCtrl.m_u32TimeOut = 5;
			PluginMonitorSearchHandleRecvNit(pu8Data);
		}
		else if (BUILDER_MONITOR_SEARCH_RECV_BAT == eMonitorStatus)
		{
			stBuilderCtrl.m_u32TimeOut = 4;
			PluginMonitorSearchHandleRecvBat(pu8Data);
		}
		else if (BUILDER_MONITOR_SEARCH_RECV_PSI == eMonitorStatus)
		{
			stBuilderCtrl.m_u32TimeOut = 4;
			s32Ret = PluginSectionDataRecv(&stBuilderCtrl.m_stSecCtrl, hFilter, pu8Data);
			if(s32Ret == 0)
			{
				s32Ret = PluginSectionDataGetProcess(&stBuilderCtrl.m_stSecCtrl, &u32Process);
				if(s32Ret == 0)
				{
					if(u32Process  == 100)
					{
						PluginMonitorCmp();
						stBuilderCtrl.m_u32Process = 100;
						stBuilderCtrl.m_u32DataOK  = 1;
						memcpy(&stBuilderCtrl.m_stDataOkTunerInfo, &stBuilderCtrl.m_stCurTuner, sizeof(builder_tuner_t));
					}
				}
				else
				{
					PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleDataRecved() - get section control process not OK\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
				}
			}
			else
			{
				PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleDataRecved() - send to section control not OK\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
			}
		}
	}
	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchHandleDataRecved() - return, s32Ret = %d\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,s32Ret);
	return s32Ret;
}

int PluginMonitorCmpData(builder_section_t *pOldData, builder_section_t *pCurData)
{
	int s32Ret = 0;
	builder_section_t *pCurSecData = pCurData;
	builder_section_t *pOldSecData = pOldData;
	int oldCrc = 0;
	int curCrc = 0;

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorCmpData enter!\r\n",  g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
	while(NULL != pOldSecData && NULL != pCurSecData)
	{
		oldCrc = SiPsiGetSectionCrc(pOldSecData->m_au8Section);
		curCrc = SiPsiGetSectionCrc(pCurSecData->m_au8Section);
		if (oldCrc != curCrc)
		{
			PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorCmpData: oldsecno=%d,cursecno=%d, CRC is different,oldCrc=0x%x,curCrc=0x%x\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,SiPsiGetSectionNo(pOldSecData->m_au8Section),SiPsiGetSectionNo(pCurSecData->m_au8Section),oldCrc,curCrc);
			s32Ret = 1;
			break;
		}
		else
		{
			PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorCmpData: oldsecno=%d,cursecno=%d, CRC is same, CRC=0x%x\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,SiPsiGetSectionNo(pOldSecData->m_au8Section),SiPsiGetSectionNo(pCurSecData->m_au8Section),oldCrc);
		}
		pOldSecData  = pOldSecData->m_pstNext;
		pCurSecData  = pCurSecData->m_pstNext;
	}

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorCmpData exit!\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
	return s32Ret;
}

int PluginMonitorCmp()
{
	int s32Ret = 0;
    int u32ChangeFlag = 0;
    unsigned char u8Idx  = 0;
	unsigned char u8TableChangeResult	= 0x0;
	unsigned char u8TableChangeCmpType	= 0x0;
	builder_section_t *pCurSecData = NULL;
	builder_section_t *pOldSecData = NULL;
	u8TableChangeCmpType = SDTTABLECHANGE | PATTABLECHANGE;

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorCmp() - entry!\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);

	while(1)
	{
		switch(u8TableChangeCmpType & (0x1<<u8Idx))
		{
			case NITTABLECHANGE:
				PluginDvbLogcat("PluginMonitorDataCmpNIT enter!\r\n");
				pOldSecData = g_stMonitorData.m_pNitSectionDb;
				pCurSecData = stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstNitSections;
				u32ChangeFlag = PluginMonitorCmpData(pOldSecData, pCurSecData);
				break;
			case BATTABLECHANGE:
				PluginDvbLogcat("PluginMonitorDataCmpBAT enter!\r\n");
				pOldSecData = g_stMonitorData.m_pBatSectionDb;
				pCurSecData = stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstBatSections;
				u32ChangeFlag = PluginMonitorCmpData(pOldSecData, pCurSecData);
				break;
			case SDTTABLECHANGE:
				PluginDvbLogcat("PluginMonitorDataCmpSDT enter!\r\n");
				pOldSecData = g_stMonitorData.m_pTsData->m_stSiPsi.m_pstSdt;
				pCurSecData = stBuilderCtrl.m_stSecCtrl.m_stSiPsi.m_pstSdt;
				u32ChangeFlag = PluginMonitorCmpData(pOldSecData, pCurSecData);
				break;
			case PATTABLECHANGE:
				PluginDvbLogcat("PluginMonitorDataCmpPAT enter!\r\n");
				pOldSecData = g_stMonitorData.m_pTsData->m_stSiPsi.m_pstPat;
				pCurSecData = stBuilderCtrl.m_stSecCtrl.m_stSiPsi.m_pstPat;
				u32ChangeFlag = PluginMonitorCmpData(pOldSecData, pCurSecData);
				break;
			case PMTTABLECHANGE:
				PluginDvbLogcat("PluginMonitorDataCmpPMT enter!\r\n");
				pOldSecData = g_stMonitorData.m_pTsData->m_stSiPsi.m_pstPmt;
				pCurSecData = stBuilderCtrl.m_stSecCtrl.m_stSiPsi.m_pstPmt;
				u32ChangeFlag = PluginMonitorCmpData(pOldSecData, pCurSecData);
				break;
		}

        if(0 != u32ChangeFlag)
        {
            u8TableChangeResult |= (0x1<<u8Idx);
            u32ChangeFlag = 0;
        }

		u8Idx++;
		if(TABLECHANGENUM == u8Idx)
		{
			break;
		}
	}

	if(stDvbFuncsList.m_pfDvbTableChangeNotify)
	{
		s32Ret = stDvbFuncsList.m_pfDvbTableChangeNotify(u8TableChangeResult);
	}

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorCmp() - return, s32Ret = %d\r\n",	g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,s32Ret);

	return s32Ret;
}

int PluginMonitorStart(builder_monitor_data_t *pstMonitorData)
{
	int s32Ret = 0;
	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorStart enter!\r\n",pstMonitorData->m_tunerInfo.m_u32Freq, pstMonitorData->m_netId, pstMonitorData->m_tsId, pstMonitorData->m_serviceId);
	g_stMonitorData = *pstMonitorData;
	stDvbFuncsList.m_pfDvbReadMonitorData(&g_stMonitorData);
	s_u8monitorStopFlag = 0;
	stBuilderCtrl.m_u32TimeOut	= 5;
	stBuilderCtrl.m_u32Process	= 0;
	stBuilderCtrl.m_u32DataOK	= 0;
	stBuilderCtrl.m_eStatus 	= BUILDER_PLUGIN_RECV_SIPSI;
	stBuilderCtrl.m_eSearchType = BUILDER_SEARCH_MONITOR_SEARCH;
	stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvDataTimes	 = 0;
	stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvBatDataTimes = 0;
	stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstNitSections 	 = NULL;
	stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_pstBatSections 	 = NULL;
	stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_eStatus = BUILDER_MONITOR_SEARCH_RECV_NIT;
	memset(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap, 0, sizeof(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap));
	memcpy(&stBuilderCtrl.m_stCurTuner, &pstMonitorData->m_tunerInfo, sizeof(builder_tuner_t));
	s32Ret = PluginRecvNit();
	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorStart exit!s32Ret=%d\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId,s32Ret);
	return s32Ret;
}

int PluginMonitorStop()
{
	int s32Ret = 0;
	
	PluginDvbLogcat("PluginMonitorStop() - entry\r\n");
	if (s_u8monitorStopFlag == 0)
	{
		s_u8monitorStopFlag = 1;
		PluginSectionDataStop(&stBuilderCtrl.m_stSecCtrl);
		PluginMonitorFreeNit();
		PluginRecvNitStop();
		stBuilderCtrl.m_u32Process = 0;
		stBuilderCtrl.m_eStatus    = BUILDER_PLUGIN_IDLE;
		stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_eStatus = BUILDER_MONITOR_SEARCH_RECV_NIT;
	}

	PluginDvbLogcat("PluginMonitorStop() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginManualSearchTick()
{
	int s32Ret = -1;
	unsigned int u32Process = 0;

	PluginDvbLogcat("PluginManualSearchTick() - entry\r\n");
	s32Ret = PluginSectionDataTick(&stBuilderCtrl.m_stSecCtrl);
	if(s32Ret == -1)
	{
		stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
		stBuilderCtrl.m_u32DataOK = 0;
		stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
		s32Ret = PluginSectionDataStop(&stBuilderCtrl.m_stSecCtrl);
	}
	else if(s32Ret == 1)//data ok, but some prog pmt timeout
	{
		PluginSectionDataGetProcess(&stBuilderCtrl.m_stSecCtrl, &u32Process);
		stBuilderCtrl.m_u32Process = MANUAL_SCAN_LOCK_PROCESS + (u32Process*(MANUAL_SCAN_SIPSI_PROCESS)/SCAN_ALL_PROCESS);//section control 90%, tuner lock 10%
		if(stBuilderCtrl.m_u32Process == 100)
		{
			memcpy(&stBuilderCtrl.m_stDataOkTunerInfo, &stBuilderCtrl.m_stCurTuner, sizeof(builder_tuner_t));
			stBuilderCtrl.m_u32DataOK = 1;
			stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
		}
		s32Ret = 0;
	}
	PluginDvbLogcat("PluginManualSearchTick() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
}

int PluginQuickSearchTick()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginQuickSearchTick() - entry\r\n");
	if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus == BUILDER_NETWORT_SEARCH_RECV_NIT)
	{
		if(stBuilderCtrl.m_u32TimeOut > 0)
		{
			stBuilderCtrl.m_u32TimeOut--;
			if(stBuilderCtrl.m_u32TimeOut == 0)
			{
				stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
				stBuilderCtrl.m_u32DataOK = 0;
				stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
				s32Ret = PluginRecvNitStop();
				if(s32Ret != 0)
					PluginDvbLogcat("PluginQuickSearchTick() - PluginRecvNitStop, error\r\n");
				
				s32Ret = PluginQuickFreeNit();
				if(s32Ret != 0)
					PluginDvbLogcat("PluginQuickSearchTick() - PluginFreeNit error\r\n");
			}
		}
		else
		{
			PluginDvbLogcat("PluginQuickSearchTick() - timeout is 0\r\n");
		}
	}
	else if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_eStatus == BUILDER_NETWORT_SEARCH_FREQ_LOOP)
	{
		s32Ret = PluginSectionDataTick(&stBuilderCtrl.m_stSecCtrl);
		if(s32Ret != 0)
		{
			stBuilderCtrl.m_u32DataOK = 0;
			s32Ret = PluginSectionDataStop(&stBuilderCtrl.m_stSecCtrl);
			if(s32Ret != 0)
				PluginDvbLogcat("PluginQuickSearchTick() -PluginSectionDataStop error\r\n");

			stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index++;
			stBuilderCtrl.m_u32Process = (QUICK_SCAN_NIT_PROCESS+QUICK_SCAN_LOCK_PROCESS) +  QUICK_SCAN_SIPSI_PROCESS*stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index/stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total;//section control 96%, tuner lock 2%, nit recv 2%
			PluginDvbLogcat("PluginQuickSearchTick() - stBuilderCtrl.m_u32Process = %d, [%d/%d]\r\n",stBuilderCtrl.m_u32Process, stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index, stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total);		
			if(stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index < stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Total)
			{
				memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stQuickCtrl.m_u32Index], sizeof(builder_tuner_t));
				PluginDvbLogcat("PluginQuickSearchTick() - start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
				s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
				stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
			}
			else
			{
				PluginSectionDataReset(&stBuilderCtrl.m_stSecCtrl);
				stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
				stBuilderCtrl.m_u32DataOK = 0;
				stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
			}
		}
	}
	PluginDvbLogcat("PluginQuickSearchTick() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginAutoSearchTick()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginAutoSearchTick() - entry\r\n");
	s32Ret = 0;
	switch(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus)
	{
		case BUILDER_AUTO_SEARCH_SCAN_NIT:
		{
			if(stBuilderCtrl.m_u32TimeOut > 0)
			{
				stBuilderCtrl.m_u32TimeOut--;
				if(stBuilderCtrl.m_u32TimeOut == 0)
				{
					stBuilderCtrl.m_u32DataOK = 0;
					stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index++;
					//stBuilderCtrl.m_u32Process = AUTO_SCAN_NIT_PROCESS*(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index - stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex)/(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex - stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex + 1);//scan nit 10%
					PluginSearchSetProcess(0, AUTO_SCAN_NIT_PROCESS, 0);
					PluginRecvNitStop();
					PluginAutoFreeNit();
					if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index < stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex)
					{
						memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index], sizeof(builder_tuner_t));
						s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
						stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
					}
					else
					{
						s32Ret = PluginAutoSearchEnterFullFreqLoop();
					}
				}
			}
			else
			{
				PluginDvbLogcat("PluginAutoSearchTick() - timeout is 0\r\n");
				s32Ret = -1;
			}
			break;
		}
		case BUILDER_AUTO_SEARCH_NIT_FREQ_LOOP:
		{
			s32Ret = PluginSectionDataTick(&stBuilderCtrl.m_stSecCtrl);
			if(s32Ret != 0)
			{
				stBuilderCtrl.m_u32DataOK = 0;
				s32Ret = PluginSectionDataStop(&stBuilderCtrl.m_stSecCtrl);
				if(s32Ret != 0)
					PluginDvbLogcat("PluginAutoSearchTick() -PluginSectionDataStop error\r\n");

				stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index++;
				//stBuilderCtrl.m_u32Process = AUTO_SCAN_NIT_PROCESS +  AUTO_SCAN_SIPSI_PROCESS*stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index/stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total;//scan nit 10%
				PluginSearchSetProcess(AUTO_SCAN_NIT_PROCESS, AUTO_SCAN_SIPSI_PROCESS, 0);

				PluginDvbLogcat("PluginAutoSearchTick() - nit stBuilderCtrl.m_u32Process = %d, [%d/%d]\r\n",stBuilderCtrl.m_u32Process, stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index, stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total);		
				if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total > stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index)
				{
					memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index], sizeof(builder_tuner_t));
					PluginDvbLogcat("PluginAutoSearchTick() - nit start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
					s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
					stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;
				}
				else
				{
					stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
					stBuilderCtrl.m_u32DataOK = 0;
					stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
				}
			}
			break;
		}
		case BUILDER_AUTO_SEARCH_FULL_FREQ_LOOP:
		{
			s32Ret = PluginSectionDataTick(&stBuilderCtrl.m_stSecCtrl);
			if(s32Ret != 0)
			{
				stBuilderCtrl.m_u32DataOK = 0;
				stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index++;
				//u32Index = stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index - stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex;
				//u32Cnt = stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex - stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex + 1;
				PluginSearchSetProcess(AUTO_SCAN_NIT_PROCESS, AUTO_SCAN_SIPSI_PROCESS, 0);

				PluginDvbLogcat("PluginAutoSearchTick() - full stBuilderCtrl.m_u32Process = %d, [%d/%d]\r\n",stBuilderCtrl.m_u32Process, stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index, stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Total);
				if(stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index <= stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex)
				{
					//stBuilderCtrl.m_u32Process = AUTO_SCAN_NIT_PROCESS + AUTO_SCAN_SIPSI_PROCESS*u32Index/u32Cnt;
					memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32Index], sizeof(builder_tuner_t));
					PluginDvbLogcat("PluginAutoSearchTick() - full start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
					s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
					stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;	
				}
				else
				{
					PluginDvbLogcat("PluginAutoSearchTick() - all freq index end [%d~%d]\r\n", stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32StartIndex, stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_u32EndIndex);
					stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
					stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
				}
			}
			break;
		}
		default:
		{
			s32Ret = -1;
			PluginDvbLogcat("PluginAutoSearchTick() - error status stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus = %d\r\n", stBuilderCtrl.m_uInnerCtrl.m_stAutoCtrl.m_eStatus);
			break;
		}
	}
	PluginDvbLogcat("PluginAutoSearchTick() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;	
}

int PluginFullSearchTick()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginFullSearchTick() - entry\r\n");	
	s32Ret = PluginSectionDataTick(&stBuilderCtrl.m_stSecCtrl);
	if(s32Ret != 0)
	{
		stBuilderCtrl.m_u32DataOK = 0;
		s32Ret = PluginSectionDataStop(&stBuilderCtrl.m_stSecCtrl);
		if(s32Ret != 0)
			PluginDvbLogcat("PluginFullSearchTick() -PluginSectionDataStop error\r\n");
		
		stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32Index++;
		PluginSearchSetProcess(0, SCAN_ALL_PROCESS, 0);
		
		if(stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32Index <= stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32EndIndex)
		{
			memcpy(&stBuilderCtrl.m_stCurTuner, &stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_pstTunerList[stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32Index], sizeof(builder_tuner_t));
			PluginDvbLogcat("PluginFullSearchTick() - start next freq stBuilderCtrl.m_stCurTuner.m_u32Freq = %d\r\n", stBuilderCtrl.m_stCurTuner.m_u32Freq);
			s32Ret = PluginDvbTunerLock(&stBuilderCtrl.m_stCurTuner);
			stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_WAITE_TUNER_LOCK;	
		}
		else
		{
			PluginDvbLogcat("PluginFullSearchTick() - all freq index end [%d~%d]\r\n", stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32StartIndex, stBuilderCtrl.m_uInnerCtrl.m_stFullCtrl.m_u32EndIndex);
			stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
		}
	}
	PluginDvbLogcat("PluginFullSearchTick() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;		
}

int PluginBootSearchTick()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginBootSearchTick() - entry\r\n");
	if(stBuilderCtrl.m_eSearchType == BUILDER_SEARCH_BOOT_UPDATE)
	{
		stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
		stBuilderCtrl.m_eStatus = BUILDER_PLUGIN_IDLE;
		stBuilderCtrl.m_u32DataOK = 0;
		stBuilderCtrl.m_u32Process = SCAN_ALL_PROCESS;
	}
	PluginDvbLogcat("PluginBootSearchTick() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;		
}


int PluginMonitorSearchTick()
{
	int s32Ret = 0;

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchTick() - entry\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
	if(stBuilderCtrl.m_u32TimeOut > 0)
	{
		stBuilderCtrl.m_u32TimeOut--;
		if(stBuilderCtrl.m_u32TimeOut == 0)
		{
			if(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_eStatus == BUILDER_MONITOR_SEARCH_RECV_NIT)
			{
				s32Ret = PluginRecvNitStop();
				if(s32Ret != 0)
				{
					PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchTick() - PluginRecvNitStop, error\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
				}

				s32Ret = PluginMonitorFreeNit();
				if(s32Ret != 0)
				{
					PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchTick() - PluginFreeNit error\r\n",g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
				}

				memset(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap, 0, sizeof(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_au8SecRecvBitmap));
				stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_u32RecvDataTimes = 0;
				stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_eStatus = BUILDER_MONITOR_SEARCH_RECV_PSI;
				stBuilderCtrl.m_u32TimeOut = 4;
				PluginSectionDataStart(&stBuilderCtrl.m_stSecCtrl);
				
			}
			else if(stBuilderCtrl.m_uInnerCtrl.m_stMonitorCtrl.m_eStatus == BUILDER_MONITOR_SEARCH_RECV_PSI)
			{
				s32Ret = PluginSectionDataStop(&stBuilderCtrl.m_stSecCtrl);
				if(s32Ret != 0)
				{
					PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchTick() -PluginSectionDataStop error\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId);
				}
				stBuilderCtrl.m_u32Process = 100;
				stBuilderCtrl.m_u32DataOK  = 0;
			}
		}
	}

	PluginDvbLogcat("[%d nid=0x%x tid=0x%x sid=0x%x]PluginMonitorSearchTick() - return, s32Ret = %d\r\n", g_stMonitorData.m_tunerInfo.m_u32Freq, g_stMonitorData.m_netId, g_stMonitorData.m_tsId, g_stMonitorData.m_serviceId, s32Ret);
	return s32Ret;
}

int PluginTick()
{
	int s32Ret = -1;
	
	PluginDvbLogcat("PluginTick() - entry stBuilderCtrl.m_eStatus=%d\r\n",stBuilderCtrl.m_eStatus);
	if(stBuilderCtrl.m_eStatus != BUILDER_PLUGIN_IDLE)
	{
		switch(stBuilderCtrl.m_eSearchType)
		{
			case BUILDER_SEARCH_MANUAL_SEARCH:
			{
				s32Ret = PluginManualSearchTick();
				break;
			}
			case BUILDER_SEARCH_NETWORK_SEARCH:
			{
				s32Ret = PluginQuickSearchTick();
				break;
			}
			case BUILDER_SEARCH_FULL_SEARCH:
			{
				s32Ret = PluginFullSearchTick();
				break;
			}
			case BUILDER_SEARCH_AUTO_SEARCH:
			{
				s32Ret = PluginAutoSearchTick();
				break;
			}
			case BUILDER_SEARCH_BOOT_UPDATE:
			{
				s32Ret = PluginBootSearchTick();
				break;
			}
			case BUILDER_SEARCH_MONITOR_SEARCH:
			{
				s32Ret = PluginMonitorSearchTick();
				break;
			}
			default:
				PluginDvbLogcat("PluginTick() - error type\r\n");
				break;
		}
	}
	else
	{
		PluginDvbLogcat("PluginTick() - receive error tick\r\n");
	}
	PluginDvbLogcat("PluginTick() - return, s32Ret = %d\r\n", s32Ret);
	return s32Ret;
}

int PluginInitialize (dvb_funcs_t* pstDvbFuncs,  plugin_funcs_t* pstPluginFuncs)
{
	int s32Ret = -1;

	memset(&stBuilderCtrl, 0, sizeof(stBuilderCtrl));
	if(pstDvbFuncs && pstPluginFuncs)
	{
		stDvbFuncsList = *pstDvbFuncs;
		pstPluginFuncs->m_u16Size = sizeof(plugin_funcs_t);
		pstPluginFuncs->m_u16Version = ICAST_PLUGIN_VERSION;
		pstPluginFuncs->m_pfPluginGetConfig = PluginGetConfig;
		pstPluginFuncs->m_pfPluginSearchStart = PluginSearchStart;
		pstPluginFuncs->m_pfPluginSeartchStop = PluginSearchStop;
		pstPluginFuncs->m_pfPluginLockFinish = PluginLockFinish;
		pstPluginFuncs->m_pfPluginGetProcss = PluginGetProcess;
		pstPluginFuncs->m_pfPluginDataRecved = PluginDataRecved;
		pstPluginFuncs->m_pfPluginGetSearchData = PluginGetSearchData;
		pstPluginFuncs->m_pfPluginProgSort = PluginProgSort;
		pstPluginFuncs->m_pfPluginMonitorStart = PluginMonitorStart;
		pstPluginFuncs->m_pfPluginMonitorStop = PluginMonitorStop;
		pstPluginFuncs->m_pfPluginTick = PluginTick;
	}

	return s32Ret;
}

int PluginDeinitialize()
{
	memset(&stDvbFuncsList, 0, sizeof(stDvbFuncsList));
	return 0;
}

const char* PluginGetDescription()
{
	return "icastbuilder-plugin:neimenggu:2.0";
}

int PluginGetMagicId()
{
	return 0;
}

